1. Project Clover database Sat Apr 27 2024 21:29:13 CDT
  2. Package net.bytebuddy.pool

File TypePool.java

 

Coverage histogram

../../../img/srcFileCovDistChart10.png
0% of files have more coverage

Code metrics

266
1,290
668
133
8,476
4,645
853
0.66
1.93
5.02
1.28

Classes

Class Line # Actions
TypePool 38 0 - 0 0
-1.0 -
TypePool.Resolution 58 0 - 0 0
-1.0 -
TypePool.Resolution.Simple 78 6 0% 6 0
1.0100%
TypePool.Resolution.Illegal 126 6 0% 6 0
1.0100%
TypePool.CacheProvider 175 0 - 0 0
-1.0 -
TypePool.CacheProvider.NoOp 209 3 0% 4 0
1.0100%
TypePool.CacheProvider.Simple 240 9 0% 7 0
1.0100%
TypePool.Empty 293 2 0% 3 2
0.660%
TypePool.AbstractBase 320 25 0% 12 0
1.0100%
TypePool.AbstractBase.Hierarchical 428 18 0% 10 4
0.8709677587.1%
TypePool.AbstractBase.ArrayTypeResolution 483 10 0% 8 0
1.0100%
TypePool.AbstractBase.RawAnnotationValue 558 10 0% 7 8
0.555555655.6%
TypePool.AbstractBase.RawEnumerationValue 623 11 0% 8 8
0.5789473757.9%
TypePool.AbstractBase.RawEnumerationValue.LazyEnumerationDescription 694 3 0% 3 0
1.0100%
TypePool.AbstractBase.RawTypeValue 716 7 0% 7 6
0.660%
TypePool.AbstractBase.RawTypeValue.Loaded 777 11 0% 8 4
0.809523881%
TypePool.AbstractBase.RawNonPrimitiveArray 826 26 0% 10 8
0.880%
TypePool.AbstractBase.RawNonPrimitiveArray.ComponentTypeReference 913 0 - 0 0
-1.0 -
TypePool.AbstractBase.RawNonPrimitiveArray.Loaded 926 38 0% 14 14
0.758620775.9%
TypePool.Default 1016 18 0% 12 3
0.990%
TypePool.Default.AnnotationRegistrant 1139 0 - 0 0
-1.0 -
TypePool.Default.AnnotationRegistrant.AbstractBase 1157 4 0% 3 0
1.0100%
TypePool.Default.AnnotationRegistrant.AbstractBase.ForTypeVariable 1199 8 0% 4 0
1.0100%
TypePool.Default.AnnotationRegistrant.AbstractBase.ForTypeVariable.WithIndex 1240 8 0% 3 0
1.0100%
TypePool.Default.AnnotationRegistrant.AbstractBase.ForTypeVariable.WithIndex.DoubleIndexed 1280 8 0% 3 0
1.0100%
TypePool.Default.AnnotationRegistrant.ForByteCodeElement 1325 4 0% 3 0
1.0100%
TypePool.Default.AnnotationRegistrant.ForByteCodeElement.WithIndex 1358 9 0% 4 1
0.928571492.9%
TypePool.Default.AnnotationRegistrant.ForTypeVariable 1406 4 0% 3 0
1.0100%
TypePool.Default.AnnotationRegistrant.ForTypeVariable.WithIndex 1440 4 0% 3 0
1.0100%
TypePool.Default.AnnotationRegistrant.ForTypeVariable.WithIndex.DoubleIndexed 1478 4 0% 3 0
1.0100%
TypePool.Default.ComponentTypeLocator 1522 0 - 0 0
-1.0 -
TypePool.Default.ComponentTypeLocator.Illegal 1536 2 0% 2 0
1.0100%
TypePool.Default.ComponentTypeLocator.ForAnnotationProperty 1558 8 0% 5 0
1.0100%
TypePool.Default.ComponentTypeLocator.ForAnnotationProperty.Bound 1612 6 0% 6 0
1.0100%
TypePool.Default.ComponentTypeLocator.ForArrayType 1674 7 0% 6 0
1.0100%
TypePool.Default.GenericTypeRegistrant 1724 0 - 0 0
-1.0 -
TypePool.Default.GenericTypeRegistrant.RejectingSignatureVisitor 1736 18 0% 18 30
0.1666666716.7%
TypePool.Default.ParameterBag 1841 11 0% 6 0
1.0100%
TypePool.Default.GenericTypeExtractor 1907 19 0% 14 2
0.9333333493.3%
TypePool.Default.GenericTypeExtractor.IncompleteToken 1993 0 - 0 0
-1.0 -
TypePool.Default.GenericTypeExtractor.IncompleteToken.AbstractBase 2045 5 0% 5 0
1.0100%
TypePool.Default.GenericTypeExtractor.IncompleteToken.AbstractBase.ForDirectBound 2082 2 0% 2 0
1.0100%
TypePool.Default.GenericTypeExtractor.IncompleteToken.AbstractBase.ForUpperBound 2098 2 0% 2 0
1.0100%
TypePool.Default.GenericTypeExtractor.IncompleteToken.AbstractBase.ForLowerBound 2114 2 0% 2 0
1.0100%
TypePool.Default.GenericTypeExtractor.IncompleteToken.ForTopLevelType 2131 7 0% 8 0
1.0100%
TypePool.Default.GenericTypeExtractor.IncompleteToken.ForInnerClass 2186 8 0% 9 1
0.941176594.1%
TypePool.Default.GenericTypeExtractor.ForSignature 2258 14 0% 9 2
0.9292%
TypePool.Default.GenericTypeExtractor.ForSignature.OfType 2342 9 0% 8 0
1.0100%
TypePool.Default.GenericTypeExtractor.ForSignature.OfType.SuperClassRegistrant 2407 5 0% 5 0
1.0100%
TypePool.Default.GenericTypeExtractor.ForSignature.OfType.InterfaceTypeRegistrant 2444 5 0% 5 0
1.0100%
TypePool.Default.GenericTypeExtractor.ForSignature.OfMethod 2482 11 0% 9 0
1.0100%
TypePool.Default.GenericTypeExtractor.ForSignature.OfMethod.ParameterTypeRegistrant 2562 5 0% 5 0
1.0100%
TypePool.Default.GenericTypeExtractor.ForSignature.OfMethod.ReturnTypeTypeRegistrant 2599 5 0% 5 0
1.0100%
TypePool.Default.GenericTypeExtractor.ForSignature.OfMethod.ExceptionTypeRegistrant 2636 5 0% 5 0
1.0100%
TypePool.Default.GenericTypeExtractor.ForSignature.OfField 2674 11 0% 6 0
1.0100%
TypePool.Default.LazyTypeDescription 2730 37 0% 23 3
0.95312595.3%
TypePool.Default.LazyTypeDescription.FieldTokenList 2969 2 0% 2 0
1.0100%
TypePool.Default.LazyTypeDescription.MethodTokenList 2985 2 0% 2 0
1.0100%
TypePool.Default.LazyTypeDescription.DeclarationContext 3002 0 - 0 0
-1.0 -
TypePool.Default.LazyTypeDescription.DeclarationContext.SelfDeclared 3046 6 0% 6 0
1.0100%
TypePool.Default.LazyTypeDescription.DeclarationContext.DeclaredInType 3088 9 0% 9 0
1.0100%
TypePool.Default.LazyTypeDescription.DeclarationContext.DeclaredInMethod 3151 19 0% 12 0
1.0100%
TypePool.Default.LazyTypeDescription.GenericTypeToken 3238 0 - 0 0
-1.0 -
TypePool.Default.LazyTypeDescription.GenericTypeToken.OfFormalTypeVariable 3297 0 - 0 0
-1.0 -
TypePool.Default.LazyTypeDescription.GenericTypeToken.ForPrimitiveType 3317 26 0% 16 15
0.558823555.9%
TypePool.Default.LazyTypeDescription.GenericTypeToken.ForPrimitiveType.LazyPrimitiveType 3440 8 0% 5 6
0.5384615753.8%
TypePool.Default.LazyTypeDescription.GenericTypeToken.ForUnboundWildcard 3505 4 0% 5 1
0.990%
TypePool.Default.LazyTypeDescription.GenericTypeToken.ForUnboundWildcard.LazyUnboundWildcard 3542 6 0% 4 0
1.0100%
TypePool.Default.LazyTypeDescription.GenericTypeToken.Resolution 3592 0 - 0 0
-1.0 -
TypePool.Default.LazyTypeDescription.GenericTypeToken.Resolution.Raw 3612 8 0% 8 0
1.0100%
TypePool.Default.LazyTypeDescription.GenericTypeToken.Resolution.Raw.RawAnnotatedType 3683 14 0% 10 1
0.9642857396.4%
TypePool.Default.LazyTypeDescription.GenericTypeToken.Resolution.Raw.RawAnnotatedType.LazyRawAnnotatedTypeList 3773 12 0% 8 8
0.6190476461.9%
TypePool.Default.LazyTypeDescription.GenericTypeToken.Resolution.Malformed 3859 8 0% 8 8
0.550%
TypePool.Default.LazyTypeDescription.GenericTypeToken.Resolution.ForType 3931 0 - 0 0
-1.0 -
TypePool.Default.LazyTypeDescription.GenericTypeToken.Resolution.ForType.Tokenized 3964 17 0% 10 0
1.0100%
TypePool.Default.LazyTypeDescription.GenericTypeToken.Resolution.ForMethod 4052 0 - 0 0
-1.0 -
TypePool.Default.LazyTypeDescription.GenericTypeToken.Resolution.ForMethod.Tokenized 4099 20 0% 12 0
1.0100%
TypePool.Default.LazyTypeDescription.GenericTypeToken.Resolution.ForField 4209 0 - 0 0
-1.0 -
TypePool.Default.LazyTypeDescription.GenericTypeToken.Resolution.ForField.Tokenized 4228 5 0% 5 0
1.0100%
TypePool.Default.LazyTypeDescription.GenericTypeToken.ForRawType 4276 7 0% 8 1
0.937593.8%
TypePool.Default.LazyTypeDescription.GenericTypeToken.ForTypeVariable 4336 10 0% 8 2
0.894736889.5%
TypePool.Default.LazyTypeDescription.GenericTypeToken.ForTypeVariable.AnnotatedTypeVariable 4392 7 0% 5 0
1.0100%
TypePool.Default.LazyTypeDescription.GenericTypeToken.ForTypeVariable.Formal 4446 6 0% 7 0
1.0100%
TypePool.Default.LazyTypeDescription.GenericTypeToken.ForTypeVariable.Formal.LazyTypeVariable 4509 10 0% 5 0
1.0100%
TypePool.Default.LazyTypeDescription.GenericTypeToken.ForTypeVariable.Formal.LazyTypeVariable.LazyBoundTokenList 4588 7 0% 5 0
1.0100%
TypePool.Default.LazyTypeDescription.GenericTypeToken.ForGenericArray 4653 7 0% 7 0
1.0100%
TypePool.Default.LazyTypeDescription.GenericTypeToken.ForGenericArray.LazyGenericArray 4705 7 0% 3 0
1.0100%
TypePool.Default.LazyTypeDescription.GenericTypeToken.ForLowerBoundWildcard 4768 7 0% 7 0
1.0100%
TypePool.Default.LazyTypeDescription.GenericTypeToken.ForLowerBoundWildcard.LazyLowerBoundWildcard 4820 8 0% 4 0
1.0100%
TypePool.Default.LazyTypeDescription.GenericTypeToken.ForUpperBoundWildcard 4888 7 0% 7 0
1.0100%
TypePool.Default.LazyTypeDescription.GenericTypeToken.ForUpperBoundWildcard.LazyUpperBoundWildcard 4943 8 0% 4 0
1.0100%
TypePool.Default.LazyTypeDescription.GenericTypeToken.ForParameterizedType 5011 8 0% 7 0
1.0100%
TypePool.Default.LazyTypeDescription.GenericTypeToken.ForParameterizedType.Nested 5072 17 0% 10 4
0.8571428785.7%
TypePool.Default.LazyTypeDescription.GenericTypeToken.ForParameterizedType.Nested.LazyParameterizedType 5150 11 0% 5 0
1.0100%
TypePool.Default.LazyTypeDescription.GenericTypeToken.ForParameterizedType.LazyParameterizedType 5239 11 0% 6 0
1.0100%
TypePool.Default.LazyTypeDescription.GenericTypeToken.LazyTokenList 5323 7 0% 3 0
1.0100%
TypePool.Default.LazyTypeDescription.GenericTypeToken.LazyTokenList.ForWildcardBound 5384 9 0% 4 2
0.8571428785.7%
TypePool.Default.LazyTypeDescription.AnnotationToken 5450 16 0% 11 0
1.0100%
TypePool.Default.LazyTypeDescription.AnnotationToken.Resolution 5532 0 - 0 0
-1.0 -
TypePool.Default.LazyTypeDescription.AnnotationToken.Resolution.Simple 5551 6 0% 6 0
1.0100%
TypePool.Default.LazyTypeDescription.AnnotationToken.Resolution.Illegal 5599 6 0% 6 0
1.0100%
TypePool.Default.LazyTypeDescription.FieldToken 5649 21 0% 8 0
1.0100%
TypePool.Default.LazyTypeDescription.MethodToken 5760 39 0% 8 0
1.0100%
TypePool.Default.LazyTypeDescription.MethodToken.ParameterToken 5981 16 0% 15 0
1.0100%
TypePool.Default.LazyTypeDescription.LazyAnnotationDescription 6077 21 0% 12 2
0.9487179594.9%
TypePool.Default.LazyTypeDescription.LazyAnnotationDescription.Loadable 6174 10 0% 7 5
0.666666766.7%
TypePool.Default.LazyTypeDescription.LazyPackageDescription 6230 5 0% 4 0
1.0100%
TypePool.Default.LazyTypeDescription.LazyTypeList 6270 13 0% 6 8
0.660%
TypePool.Default.LazyTypeDescription.TokenizedGenericType 6328 11 0% 8 0
1.0100%
TypePool.Default.LazyTypeDescription.TokenizedGenericType.TokenList 6432 8 0% 5 0
1.0100%
TypePool.Default.LazyTypeDescription.TokenizedGenericType.TypeVariableList 6501 7 0% 3 0
1.0100%
TypePool.Default.LazyTypeDescription.TokenizedGenericType.Malformed 6564 5 0% 4 4
0.555555655.6%
TypePool.Default.LazyTypeDescription.TokenizedGenericType.Malformed.TokenList 6605 5 0% 4 2
0.777777877.8%
TypePool.Default.LazyTypeDescription.LazyFieldDescription 6650 11 0% 6 0
1.0100%
TypePool.Default.LazyTypeDescription.LazyMethodDescription 6735 49 0% 21 2
0.97435997.4%
TypePool.Default.LazyTypeDescription.LazyMethodDescription.LazyParameterList 6976 7 0% 7 9
0.440%
TypePool.Default.LazyTypeDescription.LazyMethodDescription.LazyParameterDescription 7007 9 0% 11 0
1.0100%
TypePool.Default.LazyTypeDescription.LazyMethodDescription.LazyParameterizedReceiverType 7071 13 0% 11 2
0.923076992.3%
TypePool.Default.LazyTypeDescription.LazyMethodDescription.LazyParameterizedReceiverType.TypeArgumentList 7137 3 0% 3 0
1.0100%
TypePool.Default.LazyTypeDescription.LazyMethodDescription.LazyParameterizedReceiverType.TypeArgumentList.AnnotatedTypeVariable 7166 6 0% 5 4
0.636363663.6%
TypePool.Default.LazyTypeDescription.LazyMethodDescription.LazyNonGenericReceiverType 7217 10 0% 8 2
0.990%
TypePool.Default.TypeExtractor 7273 47 0% 23 9
0.8732394687.3%
TypePool.Default.TypeExtractor.AnnotationExtractor 7499 11 0% 10 0
1.0100%
TypePool.Default.TypeExtractor.AnnotationExtractor.ArrayLookup 7589 6 0% 4 0
1.0100%
TypePool.Default.TypeExtractor.AnnotationExtractor.AnnotationLookup 7642 6 0% 4 0
1.0100%
TypePool.Default.TypeExtractor.FieldExtractor 7696 19 0% 6 2
0.916666791.7%
TypePool.Default.TypeExtractor.MethodExtractor 7796 51 0% 23 2
0.971014597.1%
TypePool.Default.ReaderMode 8060 4 0% 4 0
1.0100%
TypePool.LazyFacade 8117 7 0% 6 0
1.0100%
TypePool.LazyFacade.LazyResolution 8165 14 0% 9 0
1.0100%
TypePool.LazyFacade.LazyResolution.LazyTypeDescription 8224 19 0% 18 0
1.0100%
TypePool.ClassLoading 8342 20 0% 15 3
0.9210526392.1%
TypePool.Explicit 8428 9 0% 6 0
1.0100%
 

Contributing tests

This file is covered by 1776 tests. .

Source view

1    package net.bytebuddy.pool;
2   
3    import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
4    import net.bytebuddy.description.TypeVariableSource;
5    import net.bytebuddy.description.annotation.AnnotationDescription;
6    import net.bytebuddy.description.annotation.AnnotationList;
7    import net.bytebuddy.description.enumeration.EnumerationDescription;
8    import net.bytebuddy.description.field.FieldDescription;
9    import net.bytebuddy.description.field.FieldList;
10    import net.bytebuddy.description.method.MethodDescription;
11    import net.bytebuddy.description.method.MethodList;
12    import net.bytebuddy.description.method.ParameterDescription;
13    import net.bytebuddy.description.method.ParameterList;
14    import net.bytebuddy.description.type.PackageDescription;
15    import net.bytebuddy.description.type.TypeDescription;
16    import net.bytebuddy.description.type.TypeList;
17    import net.bytebuddy.dynamic.ClassFileLocator;
18    import net.bytebuddy.implementation.bytecode.StackSize;
19    import net.bytebuddy.utility.PropertyDispatcher;
20    import org.objectweb.asm.*;
21    import org.objectweb.asm.signature.SignatureReader;
22    import org.objectweb.asm.signature.SignatureVisitor;
23   
24    import java.io.IOException;
25    import java.lang.annotation.Annotation;
26    import java.lang.reflect.Array;
27    import java.lang.reflect.GenericSignatureFormatError;
28    import java.lang.reflect.Proxy;
29    import java.util.*;
30    import java.util.concurrent.ConcurrentHashMap;
31    import java.util.concurrent.ConcurrentMap;
32   
33    import static net.bytebuddy.matcher.ElementMatchers.*;
34   
35    /**
36    * A type pool allows the retrieval of {@link TypeDescription} by its name.
37    */
 
38    public interface TypePool {
39   
40    /**
41    * Locates and describes the given type by its name.
42    *
43    * @param name The name of the type to describe. The name is to be written as when calling {@link Object#toString()}
44    * on a loaded {@link java.lang.Class}.
45    * @return A resolution of the type to describe. If the type to be described was found, the returned
46    * {@link net.bytebuddy.pool.TypePool.Resolution} represents this type. Otherwise, an illegal resolution is returned.
47    */
48    Resolution describe(String name);
49   
50    /**
51    * Clears this type pool's cache.
52    */
53    void clear();
54   
55    /**
56    * A resolution of a {@link net.bytebuddy.pool.TypePool} which was queried for a description.
57    */
 
58    interface Resolution {
59   
60    /**
61    * Determines if this resolution represents a {@link TypeDescription}.
62    *
63    * @return {@code true} if the queried type could be resolved.
64    */
65    boolean isResolved();
66   
67    /**
68    * Resolves this resolution to the represented type description. This method must only be invoked if this
69    * instance could be resolved. Otherwise, an exception is thrown on calling this method.
70    *
71    * @return The type description that is represented by this resolution.
72    */
73    TypeDescription resolve();
74   
75    /**
76    * A simple resolution that represents a given {@link TypeDescription}.
77    */
 
78    class Simple implements Resolution {
79   
80    /**
81    * The represented type description.
82    */
83    private final TypeDescription typeDescription;
84   
85    /**
86    * Creates a new successful resolution of a given type description.
87    *
88    * @param typeDescription The represented type description.
89    */
 
90  54841 toggle public Simple(TypeDescription typeDescription) {
91  54841 this.typeDescription = typeDescription;
92    }
93   
 
94  2055 toggle @Override
95    public boolean isResolved() {
96  2055 return true;
97    }
98   
 
99  12633 toggle @Override
100    public TypeDescription resolve() {
101  12633 return typeDescription;
102    }
103   
 
104  5 toggle @Override
105    public boolean equals(Object other) {
106  5 return this == other || !(other == null || getClass() != other.getClass())
107    && typeDescription.equals(((Simple) other).typeDescription);
108    }
109   
 
110  3 toggle @Override
111    public int hashCode() {
112  3 return typeDescription.hashCode();
113    }
114   
 
115  3 toggle @Override
116    public String toString() {
117  3 return "TypePool.Resolution.Simple{" +
118    "typeDescription=" + typeDescription +
119    '}';
120    }
121    }
122   
123    /**
124    * A canonical representation of a non-successful resolution of a {@link net.bytebuddy.pool.TypePool}.
125    */
 
126    class Illegal implements Resolution {
127   
128    /**
129    * The name of the unresolved type.
130    */
131    private final String name;
132   
133    /**
134    * Creates a new illegal resolution.
135    *
136    * @param name The name of the unresolved type.
137    */
 
138  12441 toggle public Illegal(String name) {
139  12441 this.name = name;
140    }
141   
 
142  12434 toggle @Override
143    public boolean isResolved() {
144  12434 return false;
145    }
146   
 
147  3 toggle @Override
148    public TypeDescription resolve() {
149  3 throw new IllegalStateException("Cannot resolve type description for " + name);
150    }
151   
 
152  5 toggle @Override
153    public boolean equals(Object other) {
154  5 return this == other || !(other == null || getClass() != other.getClass())
155    && name.equals(((Illegal) other).name);
156    }
157   
 
158  3 toggle @Override
159    public int hashCode() {
160  3 return name.hashCode();
161    }
162   
 
163  3 toggle @Override
164    public String toString() {
165  3 return "TypePool.Resolution.Illegal{" +
166    "name='" + name + '\'' +
167    '}';
168    }
169    }
170    }
171   
172    /**
173    * A cache provider for a {@link net.bytebuddy.pool.TypePool}.
174    */
 
175    interface CacheProvider {
176   
177    /**
178    * The value that is returned on a cache-miss.
179    */
180    Resolution UNRESOLVED = null;
181   
182    /**
183    * Attempts to find a resolution in this cache.
184    *
185    * @param name The name of the type to describe.
186    * @return A resolution of the type or {@code null} if no such resolution can be found in the cache..
187    */
188    Resolution find(String name);
189   
190    /**
191    * Registers a resolution in this cache. If a resolution to the given name already exists in the
192    * cache, it should be discarded.
193    *
194    * @param name The name of the type that is to be registered.
195    * @param resolution The resolution to register.
196    * @return The oldest version of a resolution that is currently registered in the cache which might
197    * be the given resolution or another resolution that was previously registered.
198    */
199    Resolution register(String name, Resolution resolution);
200   
201    /**
202    * Clears this cache.
203    */
204    void clear();
205   
206    /**
207    * A non-operational cache that does not store any type descriptions.
208    */
 
209    enum NoOp implements CacheProvider {
210   
211    /**
212    * The singleton instance.
213    */
214    INSTANCE;
215   
 
216  52528 toggle @Override
217    public Resolution find(String name) {
218  52528 return UNRESOLVED;
219    }
220   
 
221  52527 toggle @Override
222    public Resolution register(String name, Resolution resolution) {
223  52527 return resolution;
224    }
225   
 
226  1130 toggle @Override
227    public void clear() {
228    /* do nothing */
229    }
230   
 
231  6 toggle @Override
232    public String toString() {
233  6 return "TypePool.CacheProvider.NoOp." + name();
234    }
235    }
236   
237    /**
238    * A simple, thread-safe type cache based on a {@link java.util.concurrent.ConcurrentHashMap}.
239    */
 
240    class Simple implements CacheProvider {
241   
242    /**
243    * A map containing all cached resolutions by their names.
244    */
245    private final ConcurrentMap<String, Resolution> cache;
246   
247    /**
248    * Creates a new simple cache.
249    */
 
250  48961 toggle public Simple() {
251  48961 cache = new ConcurrentHashMap<String, Resolution>();
252    }
253   
254    /**
255    * Returns a simple cache provider that is prepopulated with the {@link Object} type.
256    *
257    * @return A simple cache provider that is prepopulated with the {@link Object} type.
258    */
 
259  48133 toggle public static CacheProvider withObjectType() {
260  48133 CacheProvider cacheProvider = new Simple();
261  48133 cacheProvider.register(Object.class.getName(), new Resolution.Simple(TypeDescription.OBJECT));
262  48133 return cacheProvider;
263    }
264   
 
265  6879 toggle @Override
266    public Resolution find(String name) {
267  6879 return cache.get(name);
268    }
269   
 
270  49078 toggle @Override
271    public Resolution register(String name, Resolution resolution) {
272  49078 Resolution cached = cache.putIfAbsent(name, resolution);
273  49078 return cached == null
274    ? resolution
275    : cached;
276    }
277   
 
278  251 toggle @Override
279    public void clear() {
280  251 cache.clear();
281    }
282   
 
283  3 toggle @Override
284    public String toString() {
285  3 return "TypePool.CacheProvider.Simple{cache=" + cache + '}';
286    }
287    }
288    }
289   
290    /**
291    * An empty type pool that cannot describe any type.
292    */
 
293    enum Empty implements TypePool {
294   
295    /**
296    * The singleton instance.
297    */
298    INSTANCE;
299   
 
300  12423 toggle @Override
301    public Resolution describe(String name) {
302  12423 return new Resolution.Illegal(name);
303    }
304   
 
305  1380 toggle @Override
306    public void clear() {
307    /* do nothing */
308    }
309   
 
310  0 toggle @Override
311    public String toString() {
312  0 return "TypePool.Empty." + name();
313    }
314    }
315   
316    /**
317    * A base implementation of a {@link net.bytebuddy.pool.TypePool} that is managing a cache provider and
318    * that handles the description of array and primitive types.
319    */
 
320    abstract class AbstractBase implements TypePool {
321   
322    /**
323    * A map of primitive types by their name.
324    */
325    protected static final Map<String, TypeDescription> PRIMITIVE_TYPES;
326   
327    /**
328    * A map of primitive types by their descriptor.
329    */
330    protected static final Map<String, String> PRIMITIVE_DESCRIPTORS;
331   
332    /**
333    * The array symbol as used by Java descriptors.
334    */
335    private static final String ARRAY_SYMBOL = "[";
336   
337    /*
338    * Initializes the maps of primitive type names and descriptors.
339    */
 
340  3 toggle static {
341  3 Map<String, TypeDescription> primitiveTypes = new HashMap<String, TypeDescription>();
342  3 Map<String, String> primitiveDescriptors = new HashMap<String, String>();
343  3 for (Class<?> primitiveType : new Class<?>[]{boolean.class,
344    byte.class,
345    short.class,
346    char.class,
347    int.class,
348    long.class,
349    float.class,
350    double.class,
351    void.class}) {
352  27 primitiveTypes.put(primitiveType.getName(), new TypeDescription.ForLoadedType(primitiveType));
353  27 primitiveDescriptors.put(Type.getDescriptor(primitiveType), primitiveType.getName());
354    }
355  3 PRIMITIVE_TYPES = Collections.unmodifiableMap(primitiveTypes);
356  3 PRIMITIVE_DESCRIPTORS = Collections.unmodifiableMap(primitiveDescriptors);
357    }
358   
359    /**
360    * The cache provider of this instance.
361    */
362    protected final CacheProvider cacheProvider;
363   
364    /**
365    * Creates a new instance.
366    *
367    * @param cacheProvider The cache provider to be used.
368    */
 
369  124067 toggle protected AbstractBase(CacheProvider cacheProvider) {
370  124067 this.cacheProvider = cacheProvider;
371    }
372   
 
373  61099 toggle @Override
374    public Resolution describe(String name) {
375  61099 if (name.contains("/")) {
376  1 throw new IllegalArgumentException(name + " contains the illegal character '/'");
377    }
378  61098 int arity = 0;
379  66420 while (name.startsWith(ARRAY_SYMBOL)) {
380  5322 arity++;
381  5322 name = name.substring(1);
382    }
383  61098 if (arity > 0) {
384  5216 String primitiveName = PRIMITIVE_DESCRIPTORS.get(name);
385  5216 name = primitiveName == null
386    ? name.substring(1, name.length() - 1)
387    : primitiveName;
388    }
389  61098 TypeDescription typeDescription = PRIMITIVE_TYPES.get(name);
390  61098 Resolution resolution = typeDescription == null
391    ? cacheProvider.find(name)
392    : new Resolution.Simple(typeDescription);
393  61098 if (resolution == null) {
394  53469 resolution = cacheProvider.register(name, doDescribe(name));
395    }
396  61098 return ArrayTypeResolution.of(resolution, arity);
397    }
398   
 
399  1380 toggle @Override
400    public void clear() {
401  1380 cacheProvider.clear();
402    }
403   
404    /**
405    * Determines a resolution to a non-primitive, non-array type.
406    *
407    * @param name The name of the type to describe.
408    * @return A resolution to the type to describe.
409    */
410    protected abstract Resolution doDescribe(String name);
411   
 
412  24 toggle @Override
413    public boolean equals(Object other) {
414  24 return this == other || !(other == null || getClass() != other.getClass())
415    && cacheProvider.equals(((AbstractBase) other).cacheProvider);
416    }
417   
 
418  25 toggle @Override
419    public int hashCode() {
420  25 return cacheProvider.hashCode();
421    }
422   
423    /**
424    * Implements a hierarchical view of type pools, similarly to class loader hierarchies. For every lookup, the parent type pool
425    * is asked first if it can resolve a type. Only if the parent (and potentially its parents) are unable to resolve a type,
426    * this instance is queried for a type description.
427    */
 
428    public abstract static class Hierarchical extends AbstractBase {
429   
430    /**
431    * The parent type pool.
432    */
433    private final TypePool parent;
434   
435    /**
436    * Creates a hierarchical type pool.
437    *
438    * @param cacheProvider The cache provider to be used.
439    * @param parent The parent type pool to be used.
440    */
 
441  75377 toggle protected Hierarchical(CacheProvider cacheProvider, TypePool parent) {
442  75377 super(cacheProvider);
443  75377 this.parent = parent;
444    }
445   
 
446  13274 toggle @Override
447    public Resolution describe(String name) {
448  13274 Resolution resolution = parent.describe(name);
449  13274 return resolution.isResolved()
450    ? resolution
451    : super.describe(name);
452    }
453   
 
454  1380 toggle @Override
455    public void clear() {
456  1380 try {
457  1380 parent.clear();
458    } finally {
459  1380 super.clear();
460    }
461    }
462   
 
463  24 toggle @Override
464    public boolean equals(Object object) {
465  24 if (this == object) return true;
466  24 if (object == null || getClass() != object.getClass()) return false;
467  6 if (!super.equals(object)) return false;
468  18 Hierarchical that = (Hierarchical) object;
469  18 return parent.equals(that.parent);
470    }
471   
 
472  25 toggle @Override
473    public int hashCode() {
474  25 int result = super.hashCode();
475  25 result = 31 * result + parent.hashCode();
476  25 return result;
477    }
478    }
479   
480    /**
481    * A resolution for a type that, if resolved, represents an array type.
482    */
 
483    protected static class ArrayTypeResolution implements Resolution {
484   
485    /**
486    * The underlying resolution that is represented by this instance.
487    */
488    private final Resolution resolution;
489   
490    /**
491    * The arity of the represented array.
492    */
493    private final int arity;
494   
495    /**
496    * Creates a wrapper for another resolution that, if resolved, represents an array type.
497    *
498    * @param resolution The underlying resolution that is represented by this instance.
499    * @param arity The arity of the represented array.
500    */
 
501  5222 toggle protected ArrayTypeResolution(Resolution resolution, int arity) {
502  5222 this.resolution = resolution;
503  5222 this.arity = arity;
504    }
505   
506    /**
507    * Creates a wrapper for another resolution that, if resolved, represents an array type. The wrapper
508    * is only created if the arity is not zero. If the arity is zero, the given resolution is simply
509    * returned instead.
510    *
511    * @param resolution The underlying resolution that is represented by this instance.
512    * @param arity The arity of the represented array.
513    * @return A wrapper for another resolution that, if resolved, represents an array type or the
514    * given resolution if the given arity is zero.
515    */
 
516  61101 toggle protected static Resolution of(Resolution resolution, int arity) {
517  61101 return arity == 0
518    ? resolution
519    : new ArrayTypeResolution(resolution, arity);
520    }
521   
 
522  2 toggle @Override
523    public boolean isResolved() {
524  2 return resolution.isResolved();
525    }
526   
 
527  5217 toggle @Override
528    public TypeDescription resolve() {
529  5217 return TypeDescription.ArrayProjection.of(resolution.resolve(), arity);
530    }
531   
 
532  7 toggle @Override
533    public boolean equals(Object other) {
534  7 return this == other || !(other == null || getClass() != other.getClass())
535    && arity == ((ArrayTypeResolution) other).arity
536    && resolution.equals(((ArrayTypeResolution) other).resolution);
537    }
538   
 
539  4 toggle @Override
540    public int hashCode() {
541  4 int result = resolution.hashCode();
542  4 result = 31 * result + arity;
543  4 return result;
544    }
545   
 
546  4 toggle @Override
547    public String toString() {
548  4 return "TypePool.AbstractBase.ArrayTypeResolution{" +
549    "resolution=" + resolution +
550    ", arity=" + arity +
551    '}';
552    }
553    }
554   
555    /**
556    * Represents a nested annotation value.
557    */
 
558    protected static class RawAnnotationValue implements AnnotationDescription.AnnotationValue<AnnotationDescription, Annotation> {
559   
560    /**
561    * The type pool to use for looking up types.
562    */
563    private final TypePool typePool;
564   
565    /**
566    * The annotation token that represents the nested invocation.
567    */
568    private final Default.LazyTypeDescription.AnnotationToken annotationToken;
569   
570    /**
571    * Creates a new annotation value for a nested annotation.
572    *
573    * @param typePool The type pool to use for looking up types.
574    * @param annotationToken The token that represents the annotation.
575    */
 
576  56 toggle public RawAnnotationValue(TypePool typePool, Default.LazyTypeDescription.AnnotationToken annotationToken) {
577  56 this.typePool = typePool;
578  56 this.annotationToken = annotationToken;
579    }
580   
 
581  46 toggle @Override
582    public AnnotationDescription resolve() {
583  46 return annotationToken.toAnnotationDescription(typePool).resolve();
584    }
585   
 
586  178 toggle @Override
587    @SuppressWarnings("unchecked")
588    public Loaded<Annotation> load(ClassLoader classLoader) throws ClassNotFoundException {
589  178 Class<?> type = classLoader.loadClass(annotationToken.getBinaryName());
590  178 if (type.isAnnotation()) {
591  178 return new ForAnnotation.Loaded<Annotation>((Annotation) Proxy.newProxyInstance(classLoader,
592    new Class<?>[]{type},
593    AnnotationDescription.AnnotationInvocationHandler.of(classLoader,
594    (Class<? extends Annotation>) type,
595    annotationToken.getValues())));
596    } else {
597  0 return new ForAnnotation.IncompatibleRuntimeType(type);
598    }
599    }
600   
 
601  0 toggle @Override
602    public boolean equals(Object other) {
603  0 return this == other || !(other == null || getClass() != other.getClass())
604    && annotationToken.equals(((RawAnnotationValue) other).annotationToken);
605    }
606   
 
607  0 toggle @Override
608    public int hashCode() {
609  0 return annotationToken.hashCode();
610    }
611   
 
612  0 toggle @Override
613    public String toString() {
614  0 return "TypePool.AbstractBase.RawAnnotationValue{" +
615    "annotationToken=" + annotationToken +
616    '}';
617    }
618    }
619   
620    /**
621    * Represents an enumeration value of an annotation.
622    */
 
623    protected static class RawEnumerationValue implements AnnotationDescription.AnnotationValue<EnumerationDescription, Enum<?>> {
624   
625    /**
626    * The type pool to use for looking up types.
627    */
628    private final TypePool typePool;
629   
630    /**
631    * The descriptor of the enumeration type.
632    */
633    private final String descriptor;
634   
635    /**
636    * The name of the enumeration.
637    */
638    private final String value;
639   
640    /**
641    * Creates a new enumeration value representation.
642    *
643    * @param typePool The type pool to use for looking up types.
644    * @param descriptor The descriptor of the enumeration type.
645    * @param value The name of the enumeration.
646    */
 
647  1810 toggle public RawEnumerationValue(TypePool typePool, String descriptor, String value) {
648  1810 this.typePool = typePool;
649  1810 this.descriptor = descriptor;
650  1810 this.value = value;
651    }
652   
 
653  69 toggle @Override
654    public EnumerationDescription resolve() {
655  69 return new LazyEnumerationDescription();
656    }
657   
 
658  180 toggle @Override
659    @SuppressWarnings("unchecked")
660    public Loaded<Enum<?>> load(ClassLoader classLoader) throws ClassNotFoundException {
661  180 Class<?> type = classLoader.loadClass(descriptor.substring(1, descriptor.length() - 1).replace('/', '.'));
662  180 try {
663  180 return type.isEnum()
664    ? new ForEnumeration.Loaded(Enum.valueOf((Class) type, value))
665    : new ForEnumeration.IncompatibleRuntimeType(type);
666    } catch (IllegalArgumentException ignored) {
667  0 return new ForEnumeration.UnknownRuntimeEnumeration((Class) type, value);
668    }
669    }
670   
 
671  0 toggle @Override
672    public boolean equals(Object other) {
673  0 return this == other || !(other == null || getClass() != other.getClass())
674    && descriptor.equals(((RawEnumerationValue) other).descriptor)
675    && value.equals(((RawEnumerationValue) other).value);
676    }
677   
 
678  0 toggle @Override
679    public int hashCode() {
680  0 return 31 * descriptor.hashCode() + value.hashCode();
681    }
682   
 
683  0 toggle @Override
684    public String toString() {
685  0 return "TypePool.DefaultLazyTypeDescription.AnnotationValue.ForEnumeration{" +
686    "descriptor='" + descriptor + '\'' +
687    ", value='" + value + '\'' +
688    '}';
689    }
690   
691    /**
692    * An enumeration description where any type references are only resolved on demand.
693    */
 
694    protected class LazyEnumerationDescription extends EnumerationDescription.AbstractBase {
695   
 
696  58 toggle @Override
697    public String getValue() {
698  58 return value;
699    }
700   
 
701  56 toggle @Override
702    public TypeDescription getEnumerationType() {
703  56 return typePool.describe(descriptor.substring(1, descriptor.length() - 1).replace('/', '.')).resolve();
704    }
705   
 
706  2 toggle @Override
707    public <T extends Enum<T>> T load(Class<T> type) {
708  2 return Enum.valueOf(type, value);
709    }
710    }
711    }
712   
713    /**
714    * Represents a type value of an annotation.
715    */
 
716    protected static class RawTypeValue implements AnnotationDescription.AnnotationValue<TypeDescription, Class<?>> {
717   
718    /**
719    * A convenience reference indicating that a loaded type should not be initialized.
720    */
721    private static final boolean NO_INITIALIZATION = false;
722   
723    /**
724    * The type pool to use for looking up types.
725    */
726    private final TypePool typePool;
727   
728    /**
729    * The binary name of the type.
730    */
731    private final String name;
732   
733    /**
734    * Represents a type value of an annotation.
735    *
736    * @param typePool The type pool to use for looking up types.
737    * @param type A type representation of the type that is referenced by the annotation..
738    */
 
739  5405 toggle public RawTypeValue(TypePool typePool, Type type) {
740  5405 this.typePool = typePool;
741  5405 name = type.getSort() == Type.ARRAY
742    ? type.getInternalName().replace('/', '.')
743    : type.getClassName();
744    }
745   
 
746  70 toggle @Override
747    public TypeDescription resolve() {
748  70 return typePool.describe(name).resolve();
749    }
750   
 
751  267 toggle @Override
752    public AnnotationDescription.AnnotationValue.Loaded<Class<?>> load(ClassLoader classLoader) throws ClassNotFoundException {
753  267 return new Loaded(Class.forName(name, NO_INITIALIZATION, classLoader));
754    }
755   
 
756  0 toggle @Override
757    public boolean equals(Object other) {
758  0 return this == other || !(other == null || getClass() != other.getClass())
759    && name.equals(((RawTypeValue) other).name);
760    }
761   
 
762  0 toggle @Override
763    public int hashCode() {
764  0 return name.hashCode();
765    }
766   
 
767  0 toggle @Override
768    public String toString() {
769  0 return "TypePool.DefaultLazyTypeDescription.AnnotationValue.ForType{" +
770    "name='" + name + '\'' +
771    '}';
772    }
773   
774    /**
775    * Represents a loaded annotation property that represents a type.
776    */
 
777    protected static class Loaded implements AnnotationDescription.AnnotationValue.Loaded<Class<?>> {
778   
779    /**
780    * The type that is represented by an annotation property.
781    */
782    private final Class<?> type;
783   
784    /**
785    * Creates a new representation for an annotation property referencing a type.
786    *
787    * @param type The type that is represented by an annotation property.
788    */
 
789  267 toggle public Loaded(Class<?> type) {
790  267 this.type = type;
791    }
792   
 
793  32 toggle @Override
794    public State getState() {
795  32 return State.RESOLVED;
796    }
797   
 
798  26 toggle @Override
799    public Class<?> resolve() {
800  26 return type;
801    }
802   
 
803  4 toggle @Override
804    public boolean equals(Object other) {
805  4 if (this == other) return true;
806  4 if (!(other instanceof AnnotationDescription.AnnotationValue.Loaded<?>)) return false;
807  4 AnnotationDescription.AnnotationValue.Loaded<?> loadedOther = (AnnotationDescription.AnnotationValue.Loaded<?>) other;
808  4 return loadedOther.getState().isResolved() && type.equals(loadedOther.resolve());
809    }
810   
 
811  9 toggle @Override
812    public int hashCode() {
813  9 return type.hashCode();
814    }
815   
 
816  6 toggle @Override
817    public String toString() {
818  6 return type.toString();
819    }
820    }
821    }
822   
823    /**
824    * Represents an array that is referenced by an annotation which does not contain primitive values.
825    */
 
826    protected static class RawNonPrimitiveArray implements AnnotationDescription.AnnotationValue<Object[], Object[]> {
827   
828    /**
829    * The type pool to use for looking up types.
830    */
831    private final TypePool typePool;
832   
833    /**
834    * A reference to the component type.
835    */
836    private final ComponentTypeReference componentTypeReference;
837   
838    /**
839    * A list of all values of this array value in their order.
840    */
841    private List<AnnotationDescription.AnnotationValue<?, ?>> value;
842   
843    /**
844    * Creates a new array value representation of a complex array.
845    *
846    * @param typePool The type pool to use for looking up types.
847    * @param componentTypeReference A lazy reference to the component type of this array.
848    * @param value A list of all values of this annotation.
849    */
 
850  639 toggle public RawNonPrimitiveArray(TypePool typePool,
851    ComponentTypeReference componentTypeReference,
852    List<AnnotationDescription.AnnotationValue<?, ?>> value) {
853  639 this.typePool = typePool;
854  639 this.value = value;
855  639 this.componentTypeReference = componentTypeReference;
856    }
857   
 
858  92 toggle @Override
859    public Object[] resolve() {
860  92 TypeDescription componentTypeDescription = typePool.describe(componentTypeReference.lookup()).resolve();
861  92 Class<?> componentType;
862  92 if (componentTypeDescription.represents(Class.class)) {
863  23 componentType = TypeDescription.class;
864  69 } else if (componentTypeDescription.isAssignableTo(Enum.class)) { // Enums can implement annotation interfaces, check this first.
865  23 componentType = EnumerationDescription.class;
866  46 } else if (componentTypeDescription.isAssignableTo(Annotation.class)) {
867  23 componentType = AnnotationDescription.class;
868  23 } else if (componentTypeDescription.represents(String.class)) {
869  23 componentType = String.class;
870    } else {
871  0 throw new IllegalStateException("Unexpected complex array component type " + componentTypeDescription);
872    }
873  92 Object[] array = (Object[]) Array.newInstance(componentType, value.size());
874  92 int index = 0;
875  92 for (AnnotationDescription.AnnotationValue<?, ?> annotationValue : value) {
876  92 Array.set(array, index++, annotationValue.resolve());
877    }
878  92 return array;
879    }
880   
 
881  356 toggle @Override
882    public AnnotationDescription.AnnotationValue.Loaded<Object[]> load(ClassLoader classLoader) throws ClassNotFoundException {
883  356 List<AnnotationDescription.AnnotationValue.Loaded<?>> loadedValues = new ArrayList<AnnotationDescription.AnnotationValue.Loaded<?>>(value.size());
884  356 for (AnnotationDescription.AnnotationValue<?, ?> value : this.value) {
885  356 loadedValues.add(value.load(classLoader));
886    }
887  356 return new Loaded(classLoader.loadClass(componentTypeReference.lookup()), loadedValues);
888    }
889   
 
890  0 toggle @Override
891    public boolean equals(Object other) {
892  0 return this == other || !(other == null || getClass() != other.getClass())
893    && componentTypeReference.equals(((RawNonPrimitiveArray) other).componentTypeReference)
894    && value.equals(((RawNonPrimitiveArray) other).value);
895    }
896   
 
897  0 toggle @Override
898    public int hashCode() {
899  0 return 31 * value.hashCode() + componentTypeReference.hashCode();
900    }
901   
 
902  0 toggle @Override
903    public String toString() {
904  0 return "TypePool.DefaultLazyTypeDescription.AnnotationValue.ForComplexArray{" +
905    "value=" + value +
906    ", componentTypeReference=" + componentTypeReference +
907    '}';
908    }
909   
910    /**
911    * A lazy representation of the component type of an array.
912    */
 
913    public interface ComponentTypeReference {
914   
915    /**
916    * Lazily returns the binary name of the array component type of an annotation value.
917    *
918    * @return The binary name of the component type.
919    */
920    String lookup();
921    }
922   
923    /**
924    * Represents a loaded annotation property representing a complex array.
925    */
 
926    protected static class Loaded implements AnnotationDescription.AnnotationValue.Loaded<Object[]> {
927   
928    /**
929    * The array's loaded component type.
930    */
931    private final Class<?> componentType;
932   
933    /**
934    * A list of loaded values of the represented complex array.
935    */
936    private final List<AnnotationDescription.AnnotationValue.Loaded<?>> values;
937   
938    /**
939    * Creates a new representation of an annotation property representing an array of
940    * non-trivial values.
941    *
942    * @param componentType The array's loaded component type.
943    * @param values A list of loaded values of the represented complex array.
944    */
 
945  356 toggle public Loaded(Class<?> componentType, List<AnnotationDescription.AnnotationValue.Loaded<?>> values) {
946  356 this.componentType = componentType;
947  356 this.values = values;
948    }
949   
 
950  40 toggle @Override
951    public State getState() {
952  40 for (AnnotationDescription.AnnotationValue.Loaded<?> value : values) {
953  40 if (!value.getState().isResolved()) {
954  0 return State.NON_RESOLVED;
955    }
956    }
957  40 return State.RESOLVED;
958    }
959   
 
960  32 toggle @Override
961    public Object[] resolve() {
962  32 Object[] array = (Object[]) Array.newInstance(componentType, values.size());
963  32 int index = 0;
964  32 for (AnnotationDescription.AnnotationValue.Loaded<?> annotationValue : values) {
965  32 Array.set(array, index++, annotationValue.resolve());
966    }
967  32 return array;
968    }
969   
 
970  8 toggle @Override
971    public boolean equals(Object other) {
972  8 if (this == other) return true;
973  8 if (!(other instanceof AnnotationDescription.AnnotationValue.Loaded<?>)) return false;
974  8 AnnotationDescription.AnnotationValue.Loaded<?> loadedOther = (AnnotationDescription.AnnotationValue.Loaded<?>) other;
975  8 if (!loadedOther.getState().isResolved()) return false;
976  8 Object otherValue = loadedOther.resolve();
977  8 if (!(otherValue instanceof Object[])) return false;
978  8 Object[] otherArrayValue = (Object[]) otherValue;
979  8 if (values.size() != otherArrayValue.length) return false;
980  8 Iterator<AnnotationDescription.AnnotationValue.Loaded<?>> iterator = values.iterator();
981  8 for (Object value : otherArrayValue) {
982  8 AnnotationDescription.AnnotationValue.Loaded<?> self = iterator.next();
983  8 if (!self.getState().isResolved() || !self.resolve().equals(value)) {
984  0 return false;
985    }
986    }
987  8 return true;
988    }
989   
 
990  12 toggle @Override
991    public int hashCode() {
992  12 int result = 1;
993  12 for (AnnotationDescription.AnnotationValue.Loaded<?> value : values) {
994  12 result = 31 * result + value.hashCode();
995    }
996  12 return result;
997    }
998   
 
999  8 toggle @Override
1000    public String toString() {
1001  8 StringBuilder stringBuilder = new StringBuilder("[");
1002  8 for (AnnotationDescription.AnnotationValue.Loaded<?> value : values) {
1003  8 stringBuilder.append(value.toString());
1004    }
1005  8 return stringBuilder.append("]").toString();
1006    }
1007    }
1008    }
1009    }
1010   
1011    /**
1012    * A default implementation of a {@link net.bytebuddy.pool.TypePool} that models binary data in the
1013    * Java byte code format into a {@link TypeDescription}. The data lookup
1014    * is delegated to a {@link net.bytebuddy.dynamic.ClassFileLocator}.
1015    */
 
1016    class Default extends AbstractBase.Hierarchical {
1017   
1018    /**
1019    * Indicates that a visited method should be ignored.
1020    */
1021    private static final MethodVisitor IGNORE_METHOD = null;
1022   
1023    /**
1024    * The locator to query for finding binary data of a type.
1025    */
1026    protected final ClassFileLocator classFileLocator;
1027   
1028    /**
1029    * The reader mode to apply by this default type pool.
1030    */
1031    protected final ReaderMode readerMode;
1032   
1033    /**
1034    * Creates a new default type pool without a parent pool.
1035    *
1036    * @param cacheProvider The cache provider to be used.
1037    * @param classFileLocator The class file locator to be used.
1038    * @param readerMode The reader mode to apply by this default type pool.
1039    */
 
1040  50094 toggle public Default(CacheProvider cacheProvider, ClassFileLocator classFileLocator, ReaderMode readerMode) {
1041  50094 this(cacheProvider, classFileLocator, readerMode, Empty.INSTANCE);
1042    }
1043   
1044    /**
1045    * Creates a new default type pool.
1046    *
1047    * @param cacheProvider The cache provider to be used.
1048    * @param classFileLocator The class file locator to be used.
1049    * @param readerMode The reader mode to apply by this default type pool.
1050    * @param parentPool The parent type pool.
1051    */
 
1052  50103 toggle public Default(CacheProvider cacheProvider, ClassFileLocator classFileLocator, ReaderMode readerMode, TypePool parentPool) {
1053  50103 super(cacheProvider, parentPool);
1054  50103 this.classFileLocator = classFileLocator;
1055  50103 this.readerMode = readerMode;
1056    }
1057   
1058    /**
1059    * Creates a default {@link net.bytebuddy.pool.TypePool} that looks up data by querying the system class
1060    * loader. The returned instance is configured to use a fast reading mode and a simple cache.
1061    *
1062    * @return A type pool that reads its data from the system class path.
1063    */
 
1064  260 toggle public static TypePool ofClassPath() {
1065  260 return of(ClassFileLocator.ForClassLoader.ofClassPath());
1066    }
1067   
1068    /**
1069    * Returns a type pool for the provided class loader.
1070    *
1071    * @param classLoader The class loader for which this class pool is representing types.
1072    * @return An appropriate type pool.
1073    */
 
1074  0 toggle public static TypePool of(ClassLoader classLoader) {
1075  0 return of(ClassFileLocator.ForClassLoader.of(classLoader));
1076    }
1077   
1078    /**
1079    * Creates a default {@link net.bytebuddy.pool.TypePool} that looks up data by querying the supplied class
1080    * file locator. The returned instance is configured to use a fast reading mode and a simple cache.
1081    *
1082    * @param classFileLocator The class file locator to use.
1083    * @return A type pool that reads its data from the system class path.
1084    */
 
1085  825 toggle public static TypePool of(ClassFileLocator classFileLocator) {
1086  825 return new Default(new CacheProvider.Simple(), classFileLocator, ReaderMode.FAST);
1087    }
1088   
 
1089  4985 toggle @Override
1090    protected Resolution doDescribe(String name) {
1091  4985 try {
1092  4985 ClassFileLocator.Resolution resolution = classFileLocator.locate(name);
1093  4985 return resolution.isResolved()
1094    ? new Resolution.Simple(parse(resolution.resolve()))
1095    : new Resolution.Illegal(name);
1096    } catch (IOException exception) {
1097  0 throw new IllegalStateException("Error while reading class file", exception);
1098    }
1099    }
1100   
1101    /**
1102    * Parses a binary representation and transforms it into a type description.
1103    *
1104    * @param binaryRepresentation The binary data to be parsed.
1105    * @return A type description of the binary data.
1106    */
 
1107  4977 toggle private TypeDescription parse(byte[] binaryRepresentation) {
1108  4977 ClassReader classReader = new ClassReader(binaryRepresentation);
1109  4977 TypeExtractor typeExtractor = new TypeExtractor();
1110  4977 classReader.accept(typeExtractor, readerMode.getFlags());
1111  4977 return typeExtractor.toTypeDescription();
1112    }
1113   
 
1114  19 toggle @Override
1115    public boolean equals(Object other) {
1116  19 return this == other || !(other == null || getClass() != other.getClass())
1117    && super.equals(other)
1118    && classFileLocator.equals(((Default) other).classFileLocator)
1119    && readerMode.equals(((Default) other).readerMode);
1120    }
1121   
 
1122  11 toggle @Override
1123    public int hashCode() {
1124  11 return 31 * (31 * super.hashCode() + classFileLocator.hashCode()) + readerMode.hashCode();
1125    }
1126   
 
1127  16 toggle @Override
1128    public String toString() {
1129  16 return "TypePool.Default{" +
1130    "classFileLocator=" + classFileLocator +
1131    ", cacheProvider=" + cacheProvider +
1132    ", readerMode=" + readerMode +
1133    '}';
1134    }
1135   
1136    /**
1137    * An annotation registrant implements a visitor pattern for reading an unknown amount of values of annotations.
1138    */
 
1139    protected interface AnnotationRegistrant {
1140   
1141    /**
1142    * Registers an annotation value.
1143    *
1144    * @param name The name of the annotation value.
1145    * @param annotationValue The value of the annotation.
1146    */
1147    void register(String name, AnnotationDescription.AnnotationValue<?, ?> annotationValue);
1148   
1149    /**
1150    * Called once all annotation values are visited.
1151    */
1152    void onComplete();
1153   
1154    /**
1155    * An abstract base implementation of an annotation registrant.
1156    */
 
1157    abstract class AbstractBase implements AnnotationRegistrant {
1158   
1159    /**
1160    * The annotation descriptor.
1161    */
1162    private final String descriptor;
1163   
1164    /**
1165    * The values that were collected so far.
1166    */
1167    private final Map<String, AnnotationDescription.AnnotationValue<?, ?>> values;
1168   
1169    /**
1170    * Creates a new annotation registrant.
1171    *
1172    * @param descriptor The annotation descriptor.
1173    */
 
1174  23014 toggle protected AbstractBase(String descriptor) {
1175  23014 this.descriptor = descriptor;
1176  23014 values = new HashMap<String, AnnotationDescription.AnnotationValue<?, ?>>();
1177    }
1178   
 
1179  11782 toggle @Override
1180    public void register(String name, AnnotationDescription.AnnotationValue<?, ?> annotationValue) {
1181  11782 values.put(name, annotationValue);
1182    }
1183   
 
1184  23000 toggle @Override
1185    public void onComplete() {
1186  23000 getTokens().add(new LazyTypeDescription.AnnotationToken(descriptor, values));
1187    }
1188   
1189    /**
1190    * Returns the token list for this collector.
1191    *
1192    * @return The token list for this collector.
1193    */
1194    protected abstract List<LazyTypeDescription.AnnotationToken> getTokens();
1195   
1196    /**
1197    * A base implementation for a collector for a type variable.
1198    */
 
1199    protected abstract static class ForTypeVariable extends AbstractBase {
1200   
1201    /**
1202    * The type variable's type path.
1203    */
1204    private final String typePath;
1205   
1206    /**
1207    * Creates a new annotation collector.
1208    *
1209    * @param descriptor The annotation descriptor.
1210    * @param typePath The type variable's type path.
1211    */
 
1212  2098 toggle protected ForTypeVariable(String descriptor, TypePath typePath) {
1213  2098 super(descriptor);
1214  2098 this.typePath = typePath == null
1215    ? LazyTypeDescription.GenericTypeToken.EMPTY_TYPE_PATH
1216    : typePath.toString();
1217    }
1218   
 
1219  2092 toggle @Override
1220    protected List<LazyTypeDescription.AnnotationToken> getTokens() {
1221  2092 Map<String, List<LazyTypeDescription.AnnotationToken>> pathMap = getPathMap();
1222  2092 List<LazyTypeDescription.AnnotationToken> tokens = pathMap.get(typePath);
1223  2092 if (tokens == null) {
1224  2078 tokens = new ArrayList<LazyTypeDescription.AnnotationToken>();
1225  2078 pathMap.put(typePath, tokens);
1226    }
1227  2092 return tokens;
1228    }
1229   
1230    /**
1231    * Returns this collector's path map.
1232    *
1233    * @return This collector's path map.
1234    */
1235    protected abstract Map<String, List<LazyTypeDescription.AnnotationToken>> getPathMap();
1236   
1237    /**
1238    * A base implementation for a collector for a type variable with an index.
1239    */
 
1240    protected abstract static class WithIndex extends AbstractBase.ForTypeVariable {
1241   
1242    /**
1243    * The type variable's index.
1244    */
1245    private final int index;
1246   
1247    /**
1248    * Creates a new annotation collector.
1249    *
1250    * @param descriptor The annotation descriptor.
1251    * @param typePath The type variable's type path.
1252    * @param index The type variable's index.
1253    */
 
1254  1324 toggle protected WithIndex(String descriptor, TypePath typePath, int index) {
1255  1324 super(descriptor, typePath);
1256  1324 this.index = index;
1257    }
1258   
 
1259  1320 toggle @Override
1260    protected Map<String, List<LazyTypeDescription.AnnotationToken>> getPathMap() {
1261  1320 Map<Integer, Map<String, List<LazyTypeDescription.AnnotationToken>>> indexedPathMap = getIndexedPathMap();
1262  1320 Map<String, List<LazyTypeDescription.AnnotationToken>> pathMap = indexedPathMap.get(index);
1263  1320 if (pathMap == null) {
1264  788 pathMap = new HashMap<String, List<LazyTypeDescription.AnnotationToken>>();
1265  788 indexedPathMap.put(index, pathMap);
1266    }
1267  1320 return pathMap;
1268    }
1269   
1270    /**
1271    * Returns this collector's indexed path map.
1272    *
1273    * @return This collector's indexed path map.
1274    */
1275    protected abstract Map<Integer, Map<String, List<LazyTypeDescription.AnnotationToken>>> getIndexedPathMap();
1276   
1277    /**
1278    * A base implementation for a collector for a type variable with two indices.
1279    */
 
1280    protected abstract static class DoubleIndexed extends WithIndex {
1281   
1282    /**
1283    * The type variable's first index.
1284    */
1285    private final int preIndex;
1286   
1287    /**
1288    * Creates a new annotation collector.
1289    *
1290    * @param descriptor The annotation descriptor.
1291    * @param typePath The type variable's type path.
1292    * @param index The type variable's index.
1293    * @param preIndex The type variable's first index.
1294    */
 
1295  496 toggle protected DoubleIndexed(String descriptor, TypePath typePath, int index, int preIndex) {
1296  496 super(descriptor, typePath, index);
1297  496 this.preIndex = preIndex;
1298    }
1299   
 
1300  494 toggle @Override
1301    protected Map<Integer, Map<String, List<LazyTypeDescription.AnnotationToken>>> getIndexedPathMap() {
1302  494 Map<Integer, Map<Integer, Map<String, List<LazyTypeDescription.AnnotationToken>>>> doubleIndexPathMap = getDoubleIndexedPathMap();
1303  494 Map<Integer, Map<String, List<LazyTypeDescription.AnnotationToken>>> indexedPathMap = doubleIndexPathMap.get(preIndex);
1304  494 if (indexedPathMap == null) {
1305  190 indexedPathMap = new HashMap<Integer, Map<String, List<LazyTypeDescription.AnnotationToken>>>();
1306  190 doubleIndexPathMap.put(preIndex, indexedPathMap);
1307    }
1308  494 return indexedPathMap;
1309    }
1310   
1311    /**
1312    * Returns this collector's double indexed path map.
1313    *
1314    * @return This collector's double indexed path map.
1315    */
1316    protected abstract Map<Integer, Map<Integer, Map<String, List<LazyTypeDescription.AnnotationToken>>>> getDoubleIndexedPathMap();
1317    }
1318    }
1319    }
1320    }
1321   
1322    /**
1323    * An annotation collector for a byte code element.
1324    */
 
1325    class ForByteCodeElement extends AbstractBase {
1326   
1327    /**
1328    * The target collection.
1329    */
1330    private final List<LazyTypeDescription.AnnotationToken> annotationTokens;
1331   
1332    /**
1333    * Creates a new annotation collector for a byte code element.
1334    *
1335    * @param descriptor The annotation descriptor.
1336    * @param annotationTokens The target collection.
1337    */
 
1338  20502 toggle protected ForByteCodeElement(String descriptor, List<LazyTypeDescription.AnnotationToken> annotationTokens) {
1339  20502 super(descriptor);
1340  20502 this.annotationTokens = annotationTokens;
1341    }
1342   
 
1343  20498 toggle @Override
1344    protected List<LazyTypeDescription.AnnotationToken> getTokens() {
1345  20498 return annotationTokens;
1346    }
1347   
 
1348  10 toggle @Override
1349    public String toString() {
1350  10 return "TypePool.Default.AnnotationRegistrant.ForByteCodeElement{" +
1351    "annotationTokens=" + annotationTokens +
1352    '}';
1353    }
1354   
1355    /**
1356    * An annotation collector for a byte code element with an index.
1357    */
 
1358    public static class WithIndex extends AbstractBase {
1359   
1360    /**
1361    * The byte code element's index.
1362    */
1363    private final int index;
1364   
1365    /**
1366    * The target collection.
1367    */
1368    private final Map<Integer, List<LazyTypeDescription.AnnotationToken>> annotationTokens;
1369   
1370    /**
1371    * Creates a new annotation collector for a byte code element with an index.
1372    *
1373    * @param descriptor The annotation descriptor.
1374    * @param index The byte code element's index.
1375    * @param annotationTokens The target collection.
1376    */
 
1377  414 toggle protected WithIndex(String descriptor, int index, Map<Integer, List<LazyTypeDescription.AnnotationToken>> annotationTokens) {
1378  414 super(descriptor);
1379  414 this.index = index;
1380  414 this.annotationTokens = annotationTokens;
1381    }
1382   
 
1383  410 toggle @Override
1384    protected List<LazyTypeDescription.AnnotationToken> getTokens() {
1385  410 List<LazyTypeDescription.AnnotationToken> annotationTokens = this.annotationTokens.get(index);
1386  410 if (annotationTokens == null) {
1387  410 annotationTokens = new ArrayList<LazyTypeDescription.AnnotationToken>();
1388  410 this.annotationTokens.put(index, annotationTokens);
1389    }
1390  410 return annotationTokens;
1391    }
1392   
 
1393  12 toggle @Override
1394    public String toString() {
1395  12 return "TypePool.Default.AnnotationRegistrant.ForByteCodeElement.WithIndex{" +
1396    "index=" + index +
1397    ", annotationTokens=" + annotationTokens +
1398    '}';
1399    }
1400    }
1401    }
1402   
1403    /**
1404    * An annotation collector for a type variable.
1405    */
 
1406    class ForTypeVariable extends AbstractBase.ForTypeVariable {
1407   
1408    /**
1409    * The target collection.
1410    */
1411    private final Map<String, List<LazyTypeDescription.AnnotationToken>> pathMap;
1412   
1413    /**
1414    * Creates a new annotation collector.
1415    *
1416    * @param descriptor The annotation descriptor.
1417    * @param typePath The type variable's type path.
1418    * @param pathMap The target collection.
1419    */
 
1420  774 toggle protected ForTypeVariable(String descriptor, TypePath typePath, Map<String, List<LazyTypeDescription.AnnotationToken>> pathMap) {
1421  774 super(descriptor, typePath);
1422  774 this.pathMap = pathMap;
1423    }
1424   
 
1425  772 toggle @Override
1426    protected Map<String, List<LazyTypeDescription.AnnotationToken>> getPathMap() {
1427  772 return pathMap;
1428    }
1429   
 
1430  5 toggle @Override
1431    public String toString() {
1432  5 return "TypePool.Default.AnnotationRegistrant.ForTypeVariable{" +
1433    ", pathMap=" + pathMap +
1434    '}';
1435    }
1436   
1437    /**
1438    * An annotation collector for a type variable with an index.
1439    */
 
1440    public static class WithIndex extends AbstractBase.ForTypeVariable.WithIndex {
1441   
1442    /**
1443    * The target collection.
1444    */
1445    private final Map<Integer, Map<String, List<LazyTypeDescription.AnnotationToken>>> indexedPathMap;
1446   
1447    /**
1448    * Creates a new annotation collector.
1449    *
1450    * @param descriptor The annotation descriptor.
1451    * @param typePath The type variable's type path.
1452    * @param index The target index.
1453    * @param indexedPathMap The target collection.
1454    */
 
1455  828 toggle protected WithIndex(String descriptor,
1456    TypePath typePath,
1457    int index,
1458    Map<Integer, Map<String, List<LazyTypeDescription.AnnotationToken>>> indexedPathMap) {
1459  828 super(descriptor, typePath, index);
1460  828 this.indexedPathMap = indexedPathMap;
1461    }
1462   
 
1463  826 toggle @Override
1464    protected Map<Integer, Map<String, List<LazyTypeDescription.AnnotationToken>>> getIndexedPathMap() {
1465  826 return indexedPathMap;
1466    }
1467   
 
1468  6 toggle @Override
1469    public String toString() {
1470  6 return "TypePool.Default.AnnotationRegistrant.ForTypeVariable.WithIndex{" +
1471    ", indexedPathMap=" + indexedPathMap +
1472    '}';
1473    }
1474   
1475    /**
1476    * An annotation collector for a type variable with two indices.
1477    */
 
1478    public static class DoubleIndexed extends AbstractBase.ForTypeVariable.WithIndex.DoubleIndexed {
1479   
1480    /**
1481    * The target collection.
1482    */
1483    private final Map<Integer, Map<Integer, Map<String, List<LazyTypeDescription.AnnotationToken>>>> doubleIndexedPathMap;
1484   
1485    /**
1486    * Creates a new annotation collector.
1487    *
1488    * @param descriptor The annotation descriptor.
1489    * @param typePath The type variable's type path.
1490    * @param index The target index.
1491    * @param preIndex The initial target index.
1492    * @param doubleIndexedPathMap The target collection.
1493    */
 
1494  496 toggle protected DoubleIndexed(String descriptor,
1495    TypePath typePath,
1496    int index,
1497    int preIndex,
1498    Map<Integer, Map<Integer, Map<String, List<LazyTypeDescription.AnnotationToken>>>> doubleIndexedPathMap) {
1499  496 super(descriptor, typePath, index, preIndex);
1500  496 this.doubleIndexedPathMap = doubleIndexedPathMap;
1501    }
1502   
 
1503  494 toggle @Override
1504    protected Map<Integer, Map<Integer, Map<String, List<LazyTypeDescription.AnnotationToken>>>> getDoubleIndexedPathMap() {
1505  494 return doubleIndexedPathMap;
1506    }
1507   
 
1508  7 toggle @Override
1509    public String toString() {
1510  7 return "TypePool.Default.AnnotationRegistrant.ForTypeVariable.WithIndex.DoubleIndexed{" +
1511    ", doubleIndexedPathMap=" + doubleIndexedPathMap +
1512    '}';
1513    }
1514    }
1515    }
1516    }
1517    }
1518   
1519    /**
1520    * A component type locator allows for the lazy location of an array's component type.
1521    */
 
1522    protected interface ComponentTypeLocator {
1523   
1524    /**
1525    * Binds this component type to a given property name of an annotation.
1526    *
1527    * @param name The name of an annotation property which the returned component type reference should
1528    * query for resolving an array's component type.
1529    * @return A component type reference to an annotation value's component type.
1530    */
1531    RawNonPrimitiveArray.ComponentTypeReference bind(String name);
1532   
1533    /**
1534    * A component type locator which cannot legally resolve an array's component type.
1535    */
 
1536    enum Illegal implements ComponentTypeLocator {
1537   
1538    /**
1539    * The singleton instance.
1540    */
1541    INSTANCE;
1542   
 
1543  1 toggle @Override
1544    public RawNonPrimitiveArray.ComponentTypeReference bind(String name) {
1545  1 throw new IllegalStateException("Unexpected lookup of component type for " + name);
1546    }
1547   
 
1548  1 toggle @Override
1549    public String toString() {
1550  1 return "TypePool.Default.ComponentTypeLocator.Illegal." + name();
1551    }
1552    }
1553   
1554    /**
1555    * A component type locator that lazily analyses an annotation for resolving an annotation property's
1556    * array value's component type.
1557    */
 
1558    class ForAnnotationProperty implements ComponentTypeLocator {
1559   
1560    /**
1561    * The type pool to query for type descriptions.
1562    */
1563    private final TypePool typePool;
1564   
1565    /**
1566    * The name of the annotation to analyze.
1567    */
1568    private final String annotationName;
1569   
1570    /**
1571    * Creates a new component type locator for an array value.
1572    *
1573    * @param typePool The type pool to be used for looking up linked types.
1574    * @param annotationDescriptor A descriptor of the annotation to analyze.
1575    */
 
1576  23061 toggle public ForAnnotationProperty(TypePool typePool, String annotationDescriptor) {
1577  23061 this.typePool = typePool;
1578  23061 annotationName = annotationDescriptor.substring(1, annotationDescriptor.length() - 1).replace('/', '.');
1579    }
1580   
 
1581  628 toggle @Override
1582    public RawNonPrimitiveArray.ComponentTypeReference bind(String name) {
1583  628 return new Bound(name);
1584    }
1585   
 
1586  6 toggle @Override
1587    public boolean equals(Object other) {
1588  6 return this == other || !(other == null || getClass() != other.getClass())
1589    && annotationName.equals(((ForAnnotationProperty) other).annotationName)
1590    && typePool.equals(((ForAnnotationProperty) other).typePool);
1591    }
1592   
 
1593  4 toggle @Override
1594    public int hashCode() {
1595  4 int result = typePool.hashCode();
1596  4 result = 31 * result + annotationName.hashCode();
1597  4 return result;
1598    }
1599   
 
1600  4 toggle @Override
1601    public String toString() {
1602  4 return "TypePool.Default.ComponentTypeLocator.ForAnnotationProperty{" +
1603    "typePool=" + typePool +
1604    ", annotationName='" + annotationName + '\'' +
1605    '}';
1606    }
1607   
1608    /**
1609    * A bound representation of a
1610    * {@link net.bytebuddy.pool.TypePool.Default.ComponentTypeLocator.ForAnnotationProperty}.
1611    */
 
1612    protected class Bound implements RawNonPrimitiveArray.ComponentTypeReference {
1613   
1614    /**
1615    * The name of the annotation property.
1616    */
1617    private final String name;
1618   
1619    /**
1620    * Creates a new bound component type locator for an annotation property.
1621    *
1622    * @param name The name of the annotation property.
1623    */
 
1624  632 toggle protected Bound(String name) {
1625  632 this.name = name;
1626    }
1627   
 
1628  449 toggle @Override
1629    public String lookup() {
1630  449 return typePool.describe(annotationName)
1631    .resolve()
1632    .getDeclaredMethods()
1633    .filter(named(name))
1634    .getOnly()
1635    .getReturnType()
1636    .asErasure()
1637    .getComponentType()
1638    .getName();
1639    }
1640   
 
1641  6 toggle @Override
1642    public boolean equals(Object other) {
1643  6 return this == other || !(other == null || getClass() != other.getClass())
1644    && name.equals(((Bound) other).name)
1645    && ForAnnotationProperty.this.equals(((Bound) other).getOuter());
1646    }
1647   
 
1648  4 toggle @Override
1649    public int hashCode() {
1650  4 return name.hashCode() + 31 * ForAnnotationProperty.this.hashCode();
1651    }
1652   
1653    /**
1654    * Returns the outer instance.
1655    *
1656    * @return The outer instance.
1657    */
 
1658  2 toggle private ForAnnotationProperty getOuter() {
1659  2 return ForAnnotationProperty.this;
1660    }
1661   
 
1662  3 toggle @Override
1663    public String toString() {
1664  3 return "TypePool.Default.ComponentTypeLocator.ForAnnotationProperty.Bound{" +
1665    "name='" + name + '\'' +
1666    '}';
1667    }
1668    }
1669    }
1670   
1671    /**
1672    * A component type locator that locates an array type by a method's return value from its method descriptor.
1673    */
 
1674    class ForArrayType implements ComponentTypeLocator, RawNonPrimitiveArray.ComponentTypeReference {
1675   
1676    /**
1677    * The resolved component type's binary name.
1678    */
1679    private final String componentType;
1680   
1681    /**
1682    * Creates a new component type locator for an array type.
1683    *
1684    * @param methodDescriptor The method descriptor to resolve.
1685    */
 
1686  89 toggle public ForArrayType(String methodDescriptor) {
1687  89 String arrayType = Type.getMethodType(methodDescriptor).getReturnType().getClassName();
1688  89 componentType = arrayType.substring(0, arrayType.length() - 2);
1689    }
1690   
 
1691  13 toggle @Override
1692    public RawNonPrimitiveArray.ComponentTypeReference bind(String name) {
1693  13 return this;
1694    }
1695   
 
1696  1 toggle @Override
1697    public String lookup() {
1698  1 return componentType;
1699    }
1700   
 
1701  5 toggle @Override
1702    public boolean equals(Object other) {
1703  5 return this == other || !(other == null || getClass() != other.getClass())
1704    && componentType.equals(((ForArrayType) other).componentType);
1705    }
1706   
 
1707  3 toggle @Override
1708    public int hashCode() {
1709  3 return componentType.hashCode();
1710    }
1711   
 
1712  3 toggle @Override
1713    public String toString() {
1714  3 return "TypePool.Default.ComponentTypeLocator.ForArrayType{" +
1715    "componentType='" + componentType + '\'' +
1716    '}';
1717    }
1718    }
1719    }
1720   
1721    /**
1722    * A type registrant allows to register a generic type token.
1723    */
 
1724    protected interface GenericTypeRegistrant {
1725   
1726    /**
1727    * Registers a discovered generic type token.
1728    *
1729    * @param token The token to be registered.
1730    */
1731    void register(LazyTypeDescription.GenericTypeToken token);
1732   
1733    /**
1734    * A signature visitor that rejects any discovered generic type.
1735    */
 
1736    class RejectingSignatureVisitor extends SignatureVisitor {
1737   
1738    /**
1739    * The message of the error message.
1740    */
1741    private static final String MESSAGE = "Unexpected token in generic signature";
1742   
1743    /**
1744    * Creates a new rejecting signature visitor.
1745    */
 
1746  64098 toggle public RejectingSignatureVisitor() {
1747  64098 super(Opcodes.ASM5);
1748    }
1749   
 
1750  0 toggle @Override
1751    public void visitFormalTypeParameter(String name) {
1752  0 throw new IllegalStateException(MESSAGE);
1753    }
1754   
 
1755  0 toggle @Override
1756    public SignatureVisitor visitClassBound() {
1757  0 throw new IllegalStateException(MESSAGE);
1758    }
1759   
 
1760  0 toggle @Override
1761    public SignatureVisitor visitInterfaceBound() {
1762  0 throw new IllegalStateException(MESSAGE);
1763    }
1764   
 
1765  18 toggle @Override
1766    public SignatureVisitor visitSuperclass() {
1767  18 throw new IllegalStateException(MESSAGE);
1768    }
1769   
 
1770  0 toggle @Override
1771    public SignatureVisitor visitInterface() {
1772  0 throw new IllegalStateException(MESSAGE);
1773    }
1774   
 
1775  0 toggle @Override
1776    public SignatureVisitor visitParameterType() {
1777  0 throw new IllegalStateException(MESSAGE);
1778    }
1779   
 
1780  0 toggle @Override
1781    public SignatureVisitor visitReturnType() {
1782  0 throw new IllegalStateException(MESSAGE);
1783    }
1784   
 
1785  0 toggle @Override
1786    public SignatureVisitor visitExceptionType() {
1787  0 throw new IllegalStateException(MESSAGE);
1788    }
1789   
 
1790  0 toggle @Override
1791    public void visitBaseType(char descriptor) {
1792  0 throw new IllegalStateException(MESSAGE);
1793    }
1794   
 
1795  0 toggle @Override
1796    public void visitTypeVariable(String name) {
1797  0 throw new IllegalStateException(MESSAGE);
1798    }
1799   
 
1800  0 toggle @Override
1801    public SignatureVisitor visitArrayType() {
1802  0 throw new IllegalStateException(MESSAGE);
1803    }
1804   
 
1805  0 toggle @Override
1806    public void visitClassType(String name) {
1807  0 throw new IllegalStateException(MESSAGE);
1808    }
1809   
 
1810  0 toggle @Override
1811    public void visitInnerClassType(String name) {
1812  0 throw new IllegalStateException(MESSAGE);
1813    }
1814   
 
1815  0 toggle @Override
1816    public void visitTypeArgument() {
1817  0 throw new IllegalStateException(MESSAGE);
1818    }
1819   
 
1820  0 toggle @Override
1821    public SignatureVisitor visitTypeArgument(char wildcard) {
1822  0 throw new IllegalStateException(MESSAGE);
1823    }
1824   
 
1825  0 toggle @Override
1826    public void visitEnd() {
1827  0 throw new IllegalStateException(MESSAGE);
1828    }
1829   
 
1830  2 toggle @Override
1831    public String toString() {
1832  2 return "TypePool.Default.GenericTypeRegistrant.RejectingSignatureVisitor{}";
1833    }
1834    }
1835    }
1836   
1837    /**
1838    * A bag for collecting parameter meta information that is stored as debug information for implemented
1839    * methods.
1840    */
 
1841    protected static class ParameterBag {
1842   
1843    /**
1844    * An array of the method's parameter types.
1845    */
1846    private final Type[] parameterType;
1847   
1848    /**
1849    * A map containing the tokens that were collected until now.
1850    */
1851    private final Map<Integer, String> parameterRegistry;
1852   
1853    /**
1854    * Creates a new bag.
1855    *
1856    * @param parameterType An array of parameter types for the method on which this parameter bag
1857    * is used.
1858    */
 
1859  105213 toggle protected ParameterBag(Type[] parameterType) {
1860  105213 this.parameterType = parameterType;
1861  105213 parameterRegistry = new HashMap<Integer, String>();
1862    }
1863   
1864    /**
1865    * Registers a new parameter.
1866    *
1867    * @param offset The offset of the registered entry on the local variable array of the method.
1868    * @param name The name of the parameter.
1869    */
 
1870  28702 toggle protected void register(int offset, String name) {
1871  28702 parameterRegistry.put(offset, name);
1872    }
1873   
1874    /**
1875    * Resolves the collected parameters as a list of parameter tokens.
1876    *
1877    * @param isStatic {@code true} if the analyzed method is static.
1878    * @return A list of parameter tokens based on the collected information.
1879    */
 
1880  105131 toggle protected List<LazyTypeDescription.MethodToken.ParameterToken> resolve(boolean isStatic) {
1881  105131 List<LazyTypeDescription.MethodToken.ParameterToken> parameterTokens = new ArrayList<LazyTypeDescription.MethodToken.ParameterToken>(parameterType.length);
1882  105131 int offset = isStatic
1883    ? StackSize.ZERO.getSize()
1884    : StackSize.SINGLE.getSize();
1885  105131 for (Type aParameterType : parameterType) {
1886  102998 String name = this.parameterRegistry.get(offset);
1887  102998 parameterTokens.add(name == null
1888    ? new LazyTypeDescription.MethodToken.ParameterToken()
1889    : new LazyTypeDescription.MethodToken.ParameterToken(name));
1890  102998 offset += aParameterType.getSize();
1891    }
1892  105131 return parameterTokens;
1893    }
1894   
 
1895  40 toggle @Override
1896    public String toString() {
1897  40 return "TypePool.Default.ParameterBag{" +
1898    "parameterType=" + Arrays.toString(parameterType) +
1899    ", parameterRegistry=" + parameterRegistry +
1900    '}';
1901    }
1902    }
1903   
1904    /**
1905    * A generic type extractor allows for an iterative extraction of generic type information.
1906    */
 
1907    protected static class GenericTypeExtractor extends GenericTypeRegistrant.RejectingSignatureVisitor implements GenericTypeRegistrant {
1908   
1909    /**
1910    * A registrant that receives any discovered type.
1911    */
1912    private final GenericTypeRegistrant genericTypeRegistrant;
1913   
1914    /**
1915    * The current token that is in the process of creation.
1916    */
1917    private IncompleteToken incompleteToken;
1918   
1919    /**
1920    * Creates a new generic type extractor.
1921    *
1922    * @param genericTypeRegistrant The target to receive the complete type.
1923    */
 
1924  49627 toggle protected GenericTypeExtractor(GenericTypeRegistrant genericTypeRegistrant) {
1925  49627 this.genericTypeRegistrant = genericTypeRegistrant;
1926    }
1927   
 
1928  7213 toggle @Override
1929    public void visitBaseType(char descriptor) {
1930  7213 genericTypeRegistrant.register(LazyTypeDescription.GenericTypeToken.ForPrimitiveType.of(descriptor));
1931    }
1932   
 
1933  13181 toggle @Override
1934    public void visitTypeVariable(String name) {
1935  13181 genericTypeRegistrant.register(new LazyTypeDescription.GenericTypeToken.ForTypeVariable(name));
1936    }
1937   
 
1938  2858 toggle @Override
1939    public SignatureVisitor visitArrayType() {
1940  2858 return new GenericTypeExtractor(this);
1941    }
1942   
 
1943  2858 toggle @Override
1944    public void register(LazyTypeDescription.GenericTypeToken componentTypeToken) {
1945  2858 genericTypeRegistrant.register(new LazyTypeDescription.GenericTypeToken.ForGenericArray(componentTypeToken));
1946    }
1947   
 
1948  26355 toggle @Override
1949    public void visitClassType(String name) {
1950  26355 incompleteToken = new IncompleteToken.ForTopLevelType(name);
1951    }
1952   
 
1953  450 toggle @Override
1954    public void visitInnerClassType(String name) {
1955  450 incompleteToken = new IncompleteToken.ForInnerClass(name, incompleteToken);
1956    }
1957   
 
1958  3896 toggle @Override
1959    public void visitTypeArgument() {
1960  3896 incompleteToken.appendPlaceholder();
1961    }
1962   
 
1963  11432 toggle @Override
1964    public SignatureVisitor visitTypeArgument(char wildcard) {
1965  11432 switch (wildcard) {
1966  1135 case SignatureVisitor.SUPER:
1967  1135 return incompleteToken.appendLowerBound();
1968  1832 case SignatureVisitor.EXTENDS:
1969  1832 return incompleteToken.appendUpperBound();
1970  8465 case SignatureVisitor.INSTANCEOF:
1971  8465 return incompleteToken.appendDirectBound();
1972  0 default:
1973  0 throw new IllegalArgumentException("Unknown wildcard: " + wildcard);
1974    }
1975    }
1976   
 
1977  26355 toggle @Override
1978    public void visitEnd() {
1979  26355 genericTypeRegistrant.register(incompleteToken.toToken());
1980    }
1981   
 
1982  8 toggle @Override
1983    public String toString() {
1984  8 return "TypePool.Default.GenericTypeExtractor{" +
1985    "genericTypeRegistrant=" + genericTypeRegistrant +
1986    ", incompleteToken=" + incompleteToken +
1987    '}';
1988    }
1989   
1990    /**
1991    * An incomplete {@link LazyTypeDescription.GenericTypeToken}.
1992    */
 
1993    protected interface IncompleteToken {
1994   
1995    /**
1996    * Appends a lower bound to this token.
1997    *
1998    * @return A signature visitor for visiting the lower bound's type.
1999    */
2000    SignatureVisitor appendLowerBound();
2001   
2002    /**
2003    * Appends an upper bound to this token.
2004    *
2005    * @return A signature visitor for visiting the upper bound's type.
2006    */
2007    SignatureVisitor appendUpperBound();
2008   
2009    /**
2010    * Appends a direct bound to this token.
2011    *
2012    * @return A signature visitor for visiting the direct bound's type.
2013    */
2014    SignatureVisitor appendDirectBound();
2015   
2016    /**
2017    * Appends a placeholder to this token.
2018    */
2019    void appendPlaceholder();
2020   
2021    /**
2022    * Returns {@code true} if this token describes a type with parameters.
2023    *
2024    * @return {@code true} if this token describes a type with parameters.
2025    */
2026    boolean isParameterized();
2027   
2028    /**
2029    * Returns the name of this token.
2030    *
2031    * @return The name of this token.
2032    */
2033    String getName();
2034   
2035    /**
2036    * Converts this incomplete token to a completed token.
2037    *
2038    * @return The finalized token.
2039    */
2040    LazyTypeDescription.GenericTypeToken toToken();
2041   
2042    /**
2043    * An abstract base implementation of an incomplete token.
2044    */
 
2045    abstract class AbstractBase implements IncompleteToken {
2046   
2047    /**
2048    * The parameters of this token.
2049    */
2050    protected final List<LazyTypeDescription.GenericTypeToken> parameters;
2051   
2052    /**
2053    * Creates a new base implementation of an incomplete token.
2054    */
 
2055  26812 toggle public AbstractBase() {
2056  26812 parameters = new ArrayList<LazyTypeDescription.GenericTypeToken>();
2057    }
2058   
 
2059  8465 toggle @Override
2060    public SignatureVisitor appendDirectBound() {
2061  8465 return new GenericTypeExtractor(new ForDirectBound());
2062    }
2063   
 
2064  1832 toggle @Override
2065    public SignatureVisitor appendUpperBound() {
2066  1832 return new GenericTypeExtractor(new ForUpperBound());
2067    }
2068   
 
2069  1135 toggle @Override
2070    public SignatureVisitor appendLowerBound() {
2071  1135 return new GenericTypeExtractor(new ForLowerBound());
2072    }
2073   
 
2074  3896 toggle @Override
2075    public void appendPlaceholder() {
2076  3896 parameters.add(LazyTypeDescription.GenericTypeToken.ForUnboundWildcard.INSTANCE);
2077    }
2078   
2079    /**
2080    * A token for registering a direct bound.
2081    */
 
2082    protected class ForDirectBound implements GenericTypeRegistrant {
2083   
 
2084  8465 toggle @Override
2085    public void register(LazyTypeDescription.GenericTypeToken token) {
2086  8465 parameters.add(token);
2087    }
2088   
 
2089  2 toggle @Override
2090    public String toString() {
2091  2 return "TypePool.Default.GenericTypeExtractor.IncompleteToken.AbstractBase.ForDirectBound{outer=" + AbstractBase.this + '}';
2092    }
2093    }
2094   
2095    /**
2096    * A token for registering a wildcard with an upper bound.
2097    */
 
2098    protected class ForUpperBound implements GenericTypeRegistrant {
2099   
 
2100  1832 toggle @Override
2101    public void register(LazyTypeDescription.GenericTypeToken token) {
2102  1832 parameters.add(new LazyTypeDescription.GenericTypeToken.ForUpperBoundWildcard(token));
2103    }
2104   
 
2105  2 toggle @Override
2106    public String toString() {
2107  2 return "TypePool.Default.GenericTypeExtractor.IncompleteToken.AbstractBase.ForUpperBound{outer=" + AbstractBase.this + '}';
2108    }
2109    }
2110   
2111    /**
2112    * A token for registering a wildcard with a lower bound.
2113    */
 
2114    protected class ForLowerBound implements GenericTypeRegistrant {
2115   
 
2116  1135 toggle @Override
2117    public void register(LazyTypeDescription.GenericTypeToken token) {
2118  1135 parameters.add(new LazyTypeDescription.GenericTypeToken.ForLowerBoundWildcard(token));
2119    }
2120   
 
2121  2 toggle @Override
2122    public String toString() {
2123  2 return "TypePool.Default.GenericTypeExtractor.IncompleteToken.AbstractBase.ForLowerBound{outer=" + AbstractBase.this + '}';
2124    }
2125    }
2126    }
2127   
2128    /**
2129    * An incomplete token representing a generic type without an outer type.
2130    */
 
2131    class ForTopLevelType extends AbstractBase {
2132   
2133    /**
2134    * The internal name of the type.
2135    */
2136    private final String internalName;
2137   
2138    /**
2139    * Creates a new incomplete token representing a type without an outer type.
2140    *
2141    * @param internalName The internal name of the type.
2142    */
 
2143  26358 toggle public ForTopLevelType(String internalName) {
2144  26358 this.internalName = internalName;
2145    }
2146   
 
2147  26355 toggle @Override
2148    public LazyTypeDescription.GenericTypeToken toToken() {
2149  26355 return isParameterized()
2150    ? new LazyTypeDescription.GenericTypeToken.ForParameterizedType(getName(), parameters)
2151    : new LazyTypeDescription.GenericTypeToken.ForRawType(getName());
2152    }
2153   
 
2154  26387 toggle @Override
2155    public boolean isParameterized() {
2156  26387 return !parameters.isEmpty();
2157    }
2158   
 
2159  26805 toggle @Override
2160    public String getName() {
2161  26805 return internalName.replace('/', '.');
2162    }
2163   
 
2164  5 toggle @Override
2165    public boolean equals(Object other) {
2166  5 return this == other || !(other == null || getClass() != other.getClass())
2167    && internalName.equals(((ForTopLevelType) other).internalName);
2168    }
2169   
 
2170  3 toggle @Override
2171    public int hashCode() {
2172  3 return internalName.hashCode();
2173    }
2174   
 
2175  4 toggle @Override
2176    public String toString() {
2177  4 return "TypePool.Default.GenericTypeExtractor.IncompleteToken.ForTopLevelType{" +
2178    "internalName='" + internalName + '\'' +
2179    '}';
2180    }
2181    }
2182   
2183    /**
2184    * An incomplete generic type token representing a type with an outer type.
2185    */
 
2186    class ForInnerClass extends AbstractBase {
2187   
2188    /**
2189    * The separator that indicates an inner type.
2190    */
2191    private static final char INNER_CLASS_SEPARATOR = '$';
2192   
2193    /**
2194    * The internal name of the type.
2195    */
2196    private final String internalName;
2197   
2198    /**
2199    * The token representing the outer type.
2200    */
2201    private final IncompleteToken outerTypeToken;
2202   
2203    /**
2204    * Creates a new incomplete token representing a type without an outer type.
2205    *
2206    * @param internalName The internal name of the type.
2207    * @param outerTypeToken The incomplete token representing the outer type.
2208    */
 
2209  454 toggle public ForInnerClass(String internalName, IncompleteToken outerTypeToken) {
2210  454 this.internalName = internalName;
2211  454 this.outerTypeToken = outerTypeToken;
2212    }
2213   
 
2214  450 toggle @Override
2215    public LazyTypeDescription.GenericTypeToken toToken() {
2216  450 return isParameterized() || outerTypeToken.isParameterized()
2217    ? new LazyTypeDescription.GenericTypeToken.ForParameterizedType.Nested(getName(), parameters, outerTypeToken.toToken())
2218    : new LazyTypeDescription.GenericTypeToken.ForRawType(getName());
2219    }
2220   
 
2221  450 toggle @Override
2222    public boolean isParameterized() {
2223  450 return !parameters.isEmpty() || !outerTypeToken.isParameterized();
2224    }
2225   
 
2226  450 toggle @Override
2227    public String getName() {
2228  450 return outerTypeToken.getName() + INNER_CLASS_SEPARATOR + internalName.replace('/', '.');
2229    }
2230   
 
2231  6 toggle @Override
2232    public boolean equals(Object other) {
2233  6 return this == other || !(other == null || getClass() != other.getClass())
2234    && internalName.equals(((ForInnerClass) other).internalName)
2235    && outerTypeToken.equals(((ForInnerClass) other).outerTypeToken);
2236    }
2237   
 
2238  4 toggle @Override
2239    public int hashCode() {
2240  4 return internalName.hashCode() + 31 * outerTypeToken.hashCode();
2241    }
2242   
 
2243  6 toggle @Override
2244    public String toString() {
2245  6 return "TypePool.Default.GenericTypeExtractor.IncompleteToken.ForInnerClass{" +
2246    "internalName='" + internalName + '\'' +
2247    "outerTypeToken=" + outerTypeToken +
2248    '}';
2249    }
2250    }
2251    }
2252   
2253    /**
2254    * A signature visitor for extracting a generic type resolution.
2255    *
2256    * @param <T> The type of the resolution this visitor extracts.
2257    */
 
2258    protected abstract static class ForSignature<T extends LazyTypeDescription.GenericTypeToken.Resolution>
2259    extends RejectingSignatureVisitor
2260    implements GenericTypeRegistrant {
2261   
2262    /**
2263    * The resolved type variable tokens.
2264    */
2265    protected final List<LazyTypeDescription.GenericTypeToken.OfFormalTypeVariable> typeVariableTokens;
2266   
2267    /**
2268    * The name of the currently constructed type.
2269    */
2270    protected String currentTypeParameter;
2271   
2272    /**
2273    * The bounds of the currently constructed type.
2274    */
2275    protected List<LazyTypeDescription.GenericTypeToken> currentBounds;
2276   
2277    /**
2278    * Creates a new signature visitor.
2279    */
 
2280  14469 toggle public ForSignature() {
2281  14469 typeVariableTokens = new ArrayList<LazyTypeDescription.GenericTypeToken.OfFormalTypeVariable>();
2282    }
2283   
2284    /**
2285    * Applies an extraction of a generic signature given the supplied visitor.
2286    *
2287    * @param genericSignature The generic signature to interpret.
2288    * @param visitor The visitor to apply.
2289    * @param <S> The type of the generated resolution.
2290    * @return The resolution of the supplied signature.
2291    */
 
2292  14465 toggle protected static <S extends LazyTypeDescription.GenericTypeToken.Resolution> S extract(String genericSignature, ForSignature<S> visitor) {
2293  14465 SignatureReader signatureReader = new SignatureReader(genericSignature);
2294  14465 signatureReader.accept(visitor);
2295  14438 return visitor.resolve();
2296    }
2297   
 
2298  3169 toggle @Override
2299    public void visitFormalTypeParameter(String name) {
2300  3169 collectTypeParameter();
2301  3169 currentTypeParameter = name;
2302  3169 currentBounds = new ArrayList<LazyTypeDescription.GenericTypeToken>();
2303    }
2304   
 
2305  2851 toggle @Override
2306    public SignatureVisitor visitClassBound() {
2307  2851 return new GenericTypeExtractor(this);
2308    }
2309   
 
2310  408 toggle @Override
2311    public SignatureVisitor visitInterfaceBound() {
2312  408 return new GenericTypeExtractor(this);
2313    }
2314   
 
2315  3259 toggle @Override
2316    public void register(LazyTypeDescription.GenericTypeToken token) {
2317  3259 if (currentBounds == null) {
2318  0 throw new IllegalStateException("Did not expect " + token + " before finding formal parameter");
2319    }
2320  3259 currentBounds.add(token);
2321    }
2322   
2323    /**
2324    * Collects the currently constructed type.
2325    */
 
2326  17616 toggle protected void collectTypeParameter() {
2327  17616 if (currentTypeParameter != null) {
2328  3169 typeVariableTokens.add(new LazyTypeDescription.GenericTypeToken.ForTypeVariable.Formal(currentTypeParameter, currentBounds));
2329    }
2330    }
2331   
2332    /**
2333    * Completes the current resolution.
2334    *
2335    * @return The resolved generic signature.
2336    */
2337    public abstract T resolve();
2338   
2339    /**
2340    * A parser for a generic type signature.
2341    */
 
2342    protected static class OfType extends ForSignature<LazyTypeDescription.GenericTypeToken.Resolution.ForType> {
2343   
2344    /**
2345    * The interface type's generic signatures.
2346    */
2347    private final List<LazyTypeDescription.GenericTypeToken> interfaceTypeTokens;
2348   
2349    /**
2350    * The super type's generic signature.
2351    */
2352    private LazyTypeDescription.GenericTypeToken superClassToken;
2353   
2354    /**
2355    * Creates a new parser for a type signature.
2356    */
 
2357  1932 toggle protected OfType() {
2358  1932 interfaceTypeTokens = new ArrayList<LazyTypeDescription.GenericTypeToken>();
2359    }
2360   
2361    /**
2362    * Extracts a generic type resolution of a type signature.
2363    *
2364    * @param genericSignature The signature to interpret.
2365    * @return The interpreted type signature.
2366    */
 
2367  4977 toggle public static LazyTypeDescription.GenericTypeToken.Resolution.ForType extract(String genericSignature) {
2368  4977 try {
2369  4977 return genericSignature == null
2370    ? LazyTypeDescription.GenericTypeToken.Resolution.Raw.INSTANCE
2371    : ForSignature.extract(genericSignature, new OfType());
2372    } catch (RuntimeException ignored) {
2373  9 return LazyTypeDescription.GenericTypeToken.Resolution.Malformed.INSTANCE;
2374    }
2375    }
2376   
 
2377  1930 toggle @Override
2378    public SignatureVisitor visitSuperclass() {
2379  1930 collectTypeParameter();
2380  1930 return new GenericTypeExtractor(new SuperClassRegistrant());
2381    }
2382   
 
2383  2438 toggle @Override
2384    public SignatureVisitor visitInterface() {
2385  2438 return new GenericTypeExtractor(new InterfaceTypeRegistrant());
2386    }
2387   
 
2388  1921 toggle @Override
2389    public LazyTypeDescription.GenericTypeToken.Resolution.ForType resolve() {
2390  1921 return new LazyTypeDescription.GenericTypeToken.Resolution.ForType.Tokenized(superClassToken, interfaceTypeTokens, typeVariableTokens);
2391    }
2392   
 
2393  10 toggle @Override
2394    public String toString() {
2395  10 return "TypePool.Default.GenericTypeExtractor.ForSignature.OfType{" +
2396    "currentTypeParameter='" + currentTypeParameter + '\'' +
2397    ", currentBounds=" + currentBounds +
2398    ", typeVariableTokens=" + typeVariableTokens +
2399    ", superClassToken=" + superClassToken +
2400    ", interfaceTypeTokens=" + interfaceTypeTokens +
2401    '}';
2402    }
2403   
2404    /**
2405    * A registrant for the super type.
2406    */
 
2407    protected class SuperClassRegistrant implements GenericTypeRegistrant {
2408   
 
2409  1921 toggle @Override
2410    public void register(LazyTypeDescription.GenericTypeToken token) {
2411  1921 superClassToken = token;
2412    }
2413   
 
2414  3 toggle @Override
2415    public int hashCode() {
2416  3 return OfType.this.hashCode();
2417    }
2418   
 
2419  5 toggle @Override
2420    public boolean equals(Object other) {
2421  5 return other != null
2422    && getClass() == other.getClass()
2423    && OfType.this.equals(((SuperClassRegistrant) other).getOuter());
2424    }
2425   
2426    /**
2427    * Returns the outer instance.
2428    *
2429    * @return The outer instance.
2430    */
 
2431  3 toggle private OfType getOuter() {
2432  3 return OfType.this;
2433    }
2434   
 
2435  2 toggle @Override
2436    public String toString() {
2437  2 return "TypePool.Default.GenericTypeExtractor.ForSignature.OfType.SuperClassRegistrant{outer=" + OfType.this + '}';
2438    }
2439    }
2440   
2441    /**
2442    * A registrant for the interface types.
2443    */
 
2444    protected class InterfaceTypeRegistrant implements GenericTypeRegistrant {
2445   
 
2446  2438 toggle @Override
2447    public void register(LazyTypeDescription.GenericTypeToken token) {
2448  2438 interfaceTypeTokens.add(token);
2449    }
2450   
 
2451  3 toggle @Override
2452    public int hashCode() {
2453  3 return OfType.this.hashCode();
2454    }
2455   
 
2456  5 toggle @Override
2457    public boolean equals(Object other) {
2458  5 return other != null
2459    && getClass() == other.getClass()
2460    && OfType.this.equals(((InterfaceTypeRegistrant) other).getOuter());
2461    }
2462   
2463    /**
2464    * Returns the outer instance.
2465    *
2466    * @return The outer instance.
2467    */
 
2468  3 toggle private OfType getOuter() {
2469  3 return OfType.this;
2470    }
2471   
 
2472  2 toggle @Override
2473    public String toString() {
2474  2 return "TypePool.Default.GenericTypeExtractor.ForSignature.OfType.InterfaceTypeRegistrant{outer=" + OfType.this + '}';
2475    }
2476    }
2477    }
2478   
2479    /**
2480    * A parser for a generic method signature.
2481    */
 
2482    protected static class OfMethod extends ForSignature<LazyTypeDescription.GenericTypeToken.Resolution.ForMethod> {
2483   
2484    /**
2485    * The generic parameter types.
2486    */
2487    private final List<LazyTypeDescription.GenericTypeToken> parameterTypeTokens;
2488   
2489    /**
2490    * The generic exception types.
2491    */
2492    private final List<LazyTypeDescription.GenericTypeToken> exceptionTypeTokens;
2493   
2494    /**
2495    * The generic return type.
2496    */
2497    private LazyTypeDescription.GenericTypeToken returnTypeToken;
2498   
2499    /**
2500    * Creates a parser for a generic method signature.
2501    */
 
2502  12537 toggle public OfMethod() {
2503  12537 parameterTypeTokens = new ArrayList<LazyTypeDescription.GenericTypeToken>();
2504  12537 exceptionTypeTokens = new ArrayList<LazyTypeDescription.GenericTypeToken>();
2505    }
2506   
2507    /**
2508    * Extracts a generic method resolution of a method signature.
2509    *
2510    * @param genericSignature The signature to interpret.
2511    * @return The interpreted method signature.
2512    */
 
2513  105205 toggle public static LazyTypeDescription.GenericTypeToken.Resolution.ForMethod extract(String genericSignature) {
2514  105205 try {
2515  105205 return genericSignature == null
2516    ? LazyTypeDescription.GenericTypeToken.Resolution.Raw.INSTANCE
2517    : ForSignature.extract(genericSignature, new OfMethod());
2518    } catch (RuntimeException ignored) {
2519  18 return LazyTypeDescription.GenericTypeToken.Resolution.Malformed.INSTANCE;
2520    }
2521    }
2522   
 
2523  12675 toggle @Override
2524    public SignatureVisitor visitParameterType() {
2525  12675 return new GenericTypeExtractor(new ParameterTypeRegistrant());
2526    }
2527   
 
2528  12517 toggle @Override
2529    public SignatureVisitor visitReturnType() {
2530  12517 collectTypeParameter();
2531  12517 return new GenericTypeExtractor(new ReturnTypeTypeRegistrant());
2532    }
2533   
 
2534  388 toggle @Override
2535    public SignatureVisitor visitExceptionType() {
2536  388 return new GenericTypeExtractor(new ExceptionTypeRegistrant());
2537    }
2538   
 
2539  12517 toggle @Override
2540    public LazyTypeDescription.GenericTypeToken.Resolution.ForMethod resolve() {
2541  12517 return new LazyTypeDescription.GenericTypeToken.Resolution.ForMethod.Tokenized(returnTypeToken,
2542    parameterTypeTokens,
2543    exceptionTypeTokens,
2544    typeVariableTokens);
2545    }
2546   
 
2547  14 toggle @Override
2548    public String toString() {
2549  14 return "TypePool.Default.GenericTypeExtractor.ForSignature.OfMethod{" +
2550    "currentTypeParameter='" + currentTypeParameter + '\'' +
2551    ", currentBounds=" + currentBounds +
2552    ", typeVariableTokens=" + typeVariableTokens +
2553    ", returnTypeToken=" + returnTypeToken +
2554    ", parameterTypeTokens=" + parameterTypeTokens +
2555    ", exceptionTypeTokens=" + exceptionTypeTokens +
2556    '}';
2557    }
2558   
2559    /**
2560    * A registrant for a parameter type.
2561    */
 
2562    protected class ParameterTypeRegistrant implements GenericTypeRegistrant {
2563   
 
2564  12675 toggle @Override
2565    public void register(LazyTypeDescription.GenericTypeToken token) {
2566  12675 parameterTypeTokens.add(token);
2567    }
2568   
 
2569  3 toggle @Override
2570    public int hashCode() {
2571  3 return OfMethod.this.hashCode();
2572    }
2573   
 
2574  5 toggle @Override
2575    public boolean equals(Object other) {
2576  5 return other != null
2577    && getClass() == other.getClass()
2578    && OfMethod.this.equals(((ParameterTypeRegistrant) other).getOuter());
2579    }
2580   
2581    /**
2582    * Returns the outer instance.
2583    *
2584    * @return The outer instance.
2585    */
 
2586  3 toggle private OfMethod getOuter() {
2587  3 return OfMethod.this;
2588    }
2589   
 
2590  2 toggle @Override
2591    public String toString() {
2592  2 return "TypePool.Default.GenericTypeExtractor.ForSignature.OfMethod.ParameterTypeRegistrant{outer=" + OfMethod.this + '}';
2593    }
2594    }
2595   
2596    /**
2597    * A registrant for a return type.
2598    */
 
2599    protected class ReturnTypeTypeRegistrant implements GenericTypeRegistrant {
2600   
 
2601  12517 toggle @Override
2602    public void register(LazyTypeDescription.GenericTypeToken token) {
2603  12517 returnTypeToken = token;
2604    }
2605   
 
2606  3 toggle @Override
2607    public int hashCode() {
2608  3 return OfMethod.this.hashCode();
2609    }
2610   
 
2611  5 toggle @Override
2612    public boolean equals(Object other) {
2613  5 return other != null
2614    && getClass() == other.getClass()
2615    && OfMethod.this.equals(((ReturnTypeTypeRegistrant) other).getOuter());
2616    }
2617   
2618    /**
2619    * Returns the outer instance.
2620    *
2621    * @return The outer instance.
2622    */
 
2623  3 toggle private OfMethod getOuter() {
2624  3 return OfMethod.this;
2625    }
2626   
 
2627  2 toggle @Override
2628    public String toString() {
2629  2 return "TypePool.Default.GenericTypeExtractor.ForSignature.OfMethod.ReturnTypeTypeRegistrant{outer=" + OfMethod.this + '}';
2630    }
2631    }
2632   
2633    /**
2634    * A registrant for an exception type.
2635    */
 
2636    protected class ExceptionTypeRegistrant implements GenericTypeRegistrant {
2637   
 
2638  388 toggle @Override
2639    public void register(LazyTypeDescription.GenericTypeToken token) {
2640  388 exceptionTypeTokens.add(token);
2641    }
2642   
 
2643  3 toggle @Override
2644    public int hashCode() {
2645  3 return OfMethod.this.hashCode();
2646    }
2647   
 
2648  5 toggle @Override
2649    public boolean equals(Object other) {
2650  5 return other != null
2651    && getClass() == other.getClass()
2652    && OfMethod.this.equals(((ExceptionTypeRegistrant) other).getOuter());
2653    }
2654   
2655    /**
2656    * Returns the outer instance.
2657    *
2658    * @return The outer instance.
2659    */
 
2660  3 toggle private OfMethod getOuter() {
2661  3 return OfMethod.this;
2662    }
2663   
 
2664  2 toggle @Override
2665    public String toString() {
2666  2 return "TypePool.Default.GenericTypeExtractor.ForSignature.OfMethod.ExceptionTypeRegistrant{outer=" + OfMethod.this + '}';
2667    }
2668    }
2669    }
2670   
2671    /**
2672    * A parser for a generic field signature.
2673    */
 
2674    protected static class OfField implements GenericTypeRegistrant {
2675   
2676    /**
2677    * The generic field type.
2678    */
2679    private LazyTypeDescription.GenericTypeToken fieldTypeToken;
2680   
2681    /**
2682    * Extracts a generic field resolution of a field signature.
2683    *
2684    * @param genericSignature The signature to interpret.
2685    * @return The interpreted field signature.
2686    */
 
2687  8584 toggle public static LazyTypeDescription.GenericTypeToken.Resolution.ForField extract(String genericSignature) {
2688  8584 if (genericSignature == null) {
2689  6456 return LazyTypeDescription.GenericTypeToken.Resolution.Raw.INSTANCE;
2690    } else {
2691  2128 SignatureReader signatureReader = new SignatureReader(genericSignature);
2692  2128 OfField visitor = new OfField();
2693  2128 try {
2694  2128 signatureReader.acceptType(new GenericTypeExtractor(visitor));
2695  2119 return visitor.resolve();
2696    } catch (RuntimeException ignored) {
2697  9 return LazyTypeDescription.GenericTypeToken.Resolution.Malformed.INSTANCE;
2698    }
2699    }
2700    }
2701   
 
2702  2119 toggle @Override
2703    public void register(LazyTypeDescription.GenericTypeToken token) {
2704  2119 fieldTypeToken = token;
2705    }
2706   
2707    /**
2708    * Completes the current resolution.
2709    *
2710    * @return The resolved generic signature.
2711    */
 
2712  2119 toggle protected LazyTypeDescription.GenericTypeToken.Resolution.ForField resolve() {
2713  2119 return new LazyTypeDescription.GenericTypeToken.Resolution.ForField.Tokenized(fieldTypeToken);
2714    }
2715   
 
2716  3 toggle @Override
2717    public String toString() {
2718  3 return "TypePool.Default.GenericTypeExtractor.ForSignature.OfField{" +
2719    "fieldTypeToken=" + fieldTypeToken +
2720    '}';
2721    }
2722    }
2723    }
2724    }
2725   
2726    /**
2727    * A type description that looks up any referenced {@link net.bytebuddy.description.ByteCodeElement} or
2728    * {@link AnnotationDescription} by querying a type pool at lookup time.
2729    */
 
2730    public static class LazyTypeDescription extends TypeDescription.AbstractBase.OfSimpleType {
2731   
2732    /**
2733    * The index of a super class's type annotations.
2734    */
2735    private static final int SUPER_CLASS_INDEX = -1;
2736   
2737    /**
2738    * Indicates that a type does not define a super type.
2739    */
2740    private static final String NO_SUPER_CLASS = null;
2741   
2742    /**
2743    * The type pool to be used for looking up linked types.
2744    */
2745    private final TypePool typePool;
2746   
2747    /**
2748    * The modifiers of this type.
2749    */
2750    private final int modifiers;
2751   
2752    /**
2753    * The binary name of this type.
2754    */
2755    private final String name;
2756   
2757    /**
2758    * The type's super type's descriptor or {@code null} if this type does not define a super type.
2759    */
2760    private final String superClassDescriptor;
2761   
2762    /**
2763    * The resolution of this type's generic type.
2764    */
2765    private final GenericTypeToken.Resolution.ForType signatureResolution;
2766   
2767    /**
2768    * The descriptor of this type's interfaces.
2769    */
2770    private final List<String> interfaceTypeDescriptors;
2771   
2772    /**
2773    * The declaration context of this type.
2774    */
2775    private final DeclarationContext declarationContext;
2776   
2777    /**
2778    * A list of descriptors representing the types that are declared by this type.
2779    */
2780    private final List<String> declaredTypes;
2781   
2782    /**
2783    * {@code true} if this type is an anonymous type.
2784    */
2785    private final boolean anonymousType;
2786   
2787    /**
2788    * A mapping of type annotations for this type's super type and interface types by their indices.
2789    */
2790    private final Map<Integer, Map<String, List<AnnotationToken>>> superTypeAnnotationTokens;
2791   
2792    /**
2793    * A mapping of type annotations of the type variables' type annotations by their indices.
2794    */
2795    private final Map<Integer, Map<String, List<AnnotationToken>>> typeVariableAnnotationTokens;
2796   
2797    /**
2798    * A mapping of type annotations of the type variables' bounds' type annotations by their indices and each variable's index.
2799    */
2800    private final Map<Integer, Map<Integer, Map<String, List<AnnotationToken>>>> typeVariableBoundsAnnotationTokens;
2801   
2802    /**
2803    * A list of tokens that represent the annotations of this type.
2804    */
2805    private final List<AnnotationToken> annotationTokens;
2806   
2807    /**
2808    * A list of field tokens describing the field's of this type.
2809    */
2810    private final List<FieldToken> fieldTokens;
2811   
2812    /**
2813    * A list of method tokens describing the method's of this type.
2814    */
2815    private final List<MethodToken> methodTokens;
2816   
2817    /**
2818    * Creates a new lazy type description.
2819    *
2820    * @param typePool The type pool to be used for looking up linked types.
2821    * @param modifiers The modifiers of this type.
2822    * @param name The binary name of this type.
2823    * @param superClassInternalName The internal name of this type's super type or {@code null} if no such super type is defined.
2824    * @param interfaceInternalName An array of this type's interfaces or {@code null} if this type does not define any interfaces.
2825    * @param signatureResolution The resolution of this type's generic types.
2826    * @param declarationContext The declaration context of this type.
2827    * @param declaredTypes A list of descriptors representing the types that are declared by this type.
2828    * @param anonymousType {@code true} if this type is an anonymous type.
2829    * @param superTypeAnnotationTokens A mapping of type annotations for this type's super type and interface types by their indices.
2830    * @param typeVariableAnnotationTokens A mapping of type annotations of the type variables' type annotations by their indices.
2831    * @param typeVariableBoundsAnnotationTokens A mapping of type annotations of the type variables' bounds' type annotations by their indices
2832    * and each variable's index.
2833    * @param annotationTokens A list of tokens that represent the annotations of this type.
2834    * @param fieldTokens A list of field tokens describing the field's of this type.
2835    * @param methodTokens A list of method tokens describing the method's of this type.
2836    */
 
2837  4977 toggle protected LazyTypeDescription(TypePool typePool,
2838    int modifiers,
2839    String name,
2840    String superClassInternalName,
2841    String[] interfaceInternalName,
2842    GenericTypeToken.Resolution.ForType signatureResolution,
2843    DeclarationContext declarationContext,
2844    List<String> declaredTypes,
2845    boolean anonymousType,
2846    Map<Integer, Map<String, List<AnnotationToken>>> superTypeAnnotationTokens,
2847    Map<Integer, Map<String, List<AnnotationToken>>> typeVariableAnnotationTokens,
2848    Map<Integer, Map<Integer, Map<String, List<AnnotationToken>>>> typeVariableBoundsAnnotationTokens,
2849    List<AnnotationToken> annotationTokens,
2850    List<FieldToken> fieldTokens,
2851    List<MethodToken> methodTokens) {
2852  4977 this.typePool = typePool;
2853  4977 this.modifiers = modifiers & ~(Opcodes.ACC_SUPER | Opcodes.ACC_DEPRECATED);
2854  4977 this.name = Type.getObjectType(name).getClassName();
2855  4977 this.superClassDescriptor = superClassInternalName == null
2856    ? NO_SUPER_CLASS
2857    : Type.getObjectType(superClassInternalName).getDescriptor();
2858  4977 this.signatureResolution = signatureResolution;
2859  4977 if (interfaceInternalName == null) {
2860  0 interfaceTypeDescriptors = Collections.emptyList();
2861    } else {
2862  4977 interfaceTypeDescriptors = new ArrayList<String>(interfaceInternalName.length);
2863  4977 for (String internalName : interfaceInternalName) {
2864  3550 interfaceTypeDescriptors.add(Type.getObjectType(internalName).getDescriptor());
2865    }
2866    }
2867  4977 this.declarationContext = declarationContext;
2868  4977 this.declaredTypes = declaredTypes;
2869  4977 this.anonymousType = anonymousType;
2870  4977 this.superTypeAnnotationTokens = superTypeAnnotationTokens;
2871  4977 this.typeVariableAnnotationTokens = typeVariableAnnotationTokens;
2872  4977 this.typeVariableBoundsAnnotationTokens = typeVariableBoundsAnnotationTokens;
2873  4977 this.annotationTokens = annotationTokens;
2874  4977 this.fieldTokens = fieldTokens;
2875  4977 this.methodTokens = methodTokens;
2876    }
2877   
 
2878  976 toggle @Override
2879    public Generic getSuperClass() {
2880  976 return superClassDescriptor == null || isInterface()
2881    ? Generic.UNDEFINED
2882    : signatureResolution.resolveSuperClass(superClassDescriptor, typePool, superTypeAnnotationTokens.get(SUPER_CLASS_INDEX), this);
2883    }
2884   
 
2885  759 toggle @Override
2886    public TypeList.Generic getInterfaces() {
2887  759 return signatureResolution.resolveInterfaceTypes(interfaceTypeDescriptors, typePool, superTypeAnnotationTokens, this);
2888    }
2889   
 
2890  149 toggle @Override
2891    public MethodDescription getEnclosingMethod() {
2892  149 return declarationContext.getEnclosingMethod(typePool);
2893    }
2894   
 
2895  630 toggle @Override
2896    public TypeDescription getEnclosingType() {
2897  630 return declarationContext.getEnclosingType(typePool);
2898    }
2899   
 
2900  87 toggle @Override
2901    public TypeList getDeclaredTypes() {
2902  87 return new LazyTypeList(typePool, declaredTypes);
2903    }
2904   
 
2905  103 toggle @Override
2906    public boolean isAnonymousClass() {
2907  103 return anonymousType;
2908    }
2909   
 
2910  101 toggle @Override
2911    public boolean isLocalClass() {
2912  101 return !anonymousType && declarationContext.isDeclaredInMethod();
2913    }
2914   
 
2915  91 toggle @Override
2916    public boolean isMemberClass() {
2917  91 return declarationContext.isDeclaredInType();
2918    }
2919   
 
2920  436 toggle @Override
2921    public FieldList<FieldDescription.InDefinedShape> getDeclaredFields() {
2922  436 return new FieldTokenList();
2923    }
2924   
 
2925  1361 toggle @Override
2926    public MethodList<MethodDescription.InDefinedShape> getDeclaredMethods() {
2927  1361 return new MethodTokenList();
2928    }
2929   
 
2930  81 toggle @Override
2931    public PackageDescription getPackage() {
2932  81 String name = getName();
2933  81 int index = name.lastIndexOf('.');
2934  81 return index == -1
2935    ? PackageDescription.UNDEFINED
2936    : new LazyPackageDescription(typePool, name.substring(0, index));
2937    }
2938   
 
2939  14471 toggle @Override
2940    public String getName() {
2941  14471 return name;
2942    }
2943   
 
2944  1209 toggle @Override
2945    public TypeDescription getDeclaringType() {
2946  1209 return declarationContext.isDeclaredInType()
2947    ? declarationContext.getEnclosingType(typePool)
2948    : TypeDescription.UNDEFINED;
2949    }
2950   
 
2951  3174 toggle @Override
2952    public int getModifiers() {
2953  3174 return modifiers;
2954    }
2955   
 
2956  776 toggle @Override
2957    public AnnotationList getDeclaredAnnotations() {
2958  776 return LazyAnnotationDescription.asList(typePool, annotationTokens);
2959    }
2960   
 
2961  1475 toggle @Override
2962    public TypeList.Generic getTypeVariables() {
2963  1475 return signatureResolution.resolveTypeVariables(typePool, this, typeVariableAnnotationTokens, typeVariableBoundsAnnotationTokens);
2964    }
2965   
2966    /**
2967    * A list of field tokens representing each entry as a field description.
2968    */
 
2969    protected class FieldTokenList extends FieldList.AbstractBase<FieldDescription.InDefinedShape> {
2970   
 
2971  829 toggle @Override
2972    public FieldDescription.InDefinedShape get(int index) {
2973  829 return fieldTokens.get(index).toFieldDescription(LazyTypeDescription.this);
2974    }
2975   
 
2976  1991 toggle @Override
2977    public int size() {
2978  1991 return fieldTokens.size();
2979    }
2980    }
2981   
2982    /**
2983    * A list of method tokens representing each entry as a method description.
2984    */
 
2985    protected class MethodTokenList extends MethodList.AbstractBase<MethodDescription.InDefinedShape> {
2986   
 
2987  14863 toggle @Override
2988    public MethodDescription.InDefinedShape get(int index) {
2989  14863 return methodTokens.get(index).toMethodDescription(LazyTypeDescription.this);
2990    }
2991   
 
2992  18545 toggle @Override
2993    public int size() {
2994  18545 return methodTokens.size();
2995    }
2996    }
2997   
2998    /**
2999    * A declaration context encapsulates information about whether a type was declared within another type
3000    * or within a method of another type.
3001    */
 
3002    protected interface DeclarationContext {
3003   
3004    /**
3005    * Returns the enclosing method or {@code null} if no such method exists.
3006    *
3007    * @param typePool The type pool to be used for looking up linked types.
3008    * @return A method description describing the linked type or {@code null}.
3009    */
3010    MethodDescription getEnclosingMethod(TypePool typePool);
3011   
3012    /**
3013    * Returns the enclosing type or {@code null} if no such type exists.
3014    *
3015    * @param typePool The type pool to be used for looking up linked types.
3016    * @return A type description describing the linked type or {@code null}.
3017    */
3018    TypeDescription getEnclosingType(TypePool typePool);
3019   
3020    /**
3021    * Returns {@code true} if this instance represents a self declared type.
3022    *
3023    * @return {@code true} if this instance represents a self declared type.
3024    */
3025    boolean isSelfDeclared();
3026   
3027    /**
3028    * Returns {@code true} if this instance represents a type that was declared within another type but not
3029    * within a method.
3030    *
3031    * @return {@code true} if this instance represents a type that was declared within another type but not
3032    * within a method.
3033    */
3034    boolean isDeclaredInType();
3035   
3036    /**
3037    * Returns {@code true} if this instance represents a type that was declared within a method.
3038    *
3039    * @return {@code true} if this instance represents a type that was declared within a method.
3040    */
3041    boolean isDeclaredInMethod();
3042   
3043    /**
3044    * Represents a self-declared type that is not defined within another type.
3045    */
 
3046    enum SelfDeclared implements DeclarationContext {
3047   
3048    /**
3049    * The singleton instance.
3050    */
3051    INSTANCE;
3052   
 
3053  39 toggle @Override
3054    public MethodDescription getEnclosingMethod(TypePool typePool) {
3055  39 return MethodDescription.UNDEFINED;
3056    }
3057   
 
3058  319 toggle @Override
3059    public TypeDescription getEnclosingType(TypePool typePool) {
3060  319 return TypeDescription.UNDEFINED;
3061    }
3062   
 
3063  1887 toggle @Override
3064    public boolean isSelfDeclared() {
3065  1887 return true;
3066    }
3067   
 
3068  949 toggle @Override
3069    public boolean isDeclaredInType() {
3070  949 return false;
3071    }
3072   
 
3073  45 toggle @Override
3074    public boolean isDeclaredInMethod() {
3075  45 return false;
3076    }
3077   
 
3078  1 toggle @Override
3079    public String toString() {
3080  1 return "TypePool.Default.LazyTypeDescription.DeclarationContext.SelfDeclared." + name();
3081    }
3082    }
3083   
3084    /**
3085    * A declaration context representing a type that is declared within another type but not within
3086    * a method.
3087    */
 
3088    class DeclaredInType implements DeclarationContext {
3089   
3090    /**
3091    * The binary name of the referenced type.
3092    */
3093    private final String name;
3094   
3095    /**
3096    * Creates a new declaration context for a type that is declared within another type.
3097    *
3098    * @param internalName The internal name of the declaring type.
3099    */
 
3100  1894 toggle public DeclaredInType(String internalName) {
3101  1894 name = internalName.replace('/', '.');
3102    }
3103   
 
3104  72 toggle @Override
3105    public MethodDescription getEnclosingMethod(TypePool typePool) {
3106  72 return MethodDescription.UNDEFINED;
3107    }
3108   
 
3109  610 toggle @Override
3110    public TypeDescription getEnclosingType(TypePool typePool) {
3111  610 return typePool.describe(name).resolve();
3112    }
3113   
 
3114  1 toggle @Override
3115    public boolean isSelfDeclared() {
3116  1 return false;
3117    }
3118   
 
3119  347 toggle @Override
3120    public boolean isDeclaredInType() {
3121  347 return true;
3122    }
3123   
 
3124  50 toggle @Override
3125    public boolean isDeclaredInMethod() {
3126  50 return false;
3127    }
3128   
 
3129  5 toggle @Override
3130    public boolean equals(Object other) {
3131  5 return this == other || !(other == null || getClass() != other.getClass())
3132    && name.equals(((DeclaredInType) other).name);
3133    }
3134   
 
3135  3 toggle @Override
3136    public int hashCode() {
3137  3 return name.hashCode();
3138    }
3139   
 
3140  3 toggle @Override
3141    public String toString() {
3142  3 return "TypePool.Default.LazyTypeDescription.DeclarationContext.DeclaredInType{" +
3143    "name='" + name + '\'' +
3144    '}';
3145    }
3146    }
3147   
3148    /**
3149    * A declaration context representing a type that is declared within a method of another type.
3150    */
 
3151    class DeclaredInMethod implements DeclarationContext {
3152   
3153    /**
3154    * The binary name of the declaring type.
3155    */
3156    private final String name;
3157   
3158    /**
3159    * The name of the method that is declaring a type.
3160    */
3161    private final String methodName;
3162   
3163    /**
3164    * The descriptor of the method that is declaring a type.
3165    */
3166    private final String methodDescriptor;
3167   
3168    /**
3169    * Creates a new declaration context for a method that declares a type.
3170    *
3171    * @param internalName The internal name of the declaring type.
3172    * @param methodName The name of the method that is declaring a type.
3173    * @param methodDescriptor The descriptor of the method that is declaring a type.
3174    */
 
3175  71 toggle public DeclaredInMethod(String internalName, String methodName, String methodDescriptor) {
3176  71 name = internalName.replace('/', '.');
3177  71 this.methodName = methodName;
3178  71 this.methodDescriptor = methodDescriptor;
3179    }
3180   
 
3181  41 toggle @Override
3182    public MethodDescription getEnclosingMethod(TypePool typePool) {
3183  41 return getEnclosingType(typePool).getDeclaredMethods().filter(hasMethodName(methodName).and(hasDescriptor(methodDescriptor))).getOnly();
3184    }
3185   
 
3186  44 toggle @Override
3187    public TypeDescription getEnclosingType(TypePool typePool) {
3188  44 return typePool.describe(name).resolve();
3189    }
3190   
 
3191  1 toggle @Override
3192    public boolean isSelfDeclared() {
3193  1 return false;
3194    }
3195   
 
3196  7 toggle @Override
3197    public boolean isDeclaredInType() {
3198  7 return false;
3199    }
3200   
 
3201  7 toggle @Override
3202    public boolean isDeclaredInMethod() {
3203  7 return true;
3204    }
3205   
 
3206  7 toggle @Override
3207    public boolean equals(Object other) {
3208  1 if (this == other) return true;
3209  2 if (other == null || getClass() != other.getClass()) return false;
3210  4 DeclaredInMethod that = (DeclaredInMethod) other;
3211  4 return methodDescriptor.equals(that.methodDescriptor)
3212    && methodName.equals(that.methodName)
3213    && name.equals(that.name);
3214    }
3215   
 
3216  5 toggle @Override
3217    public int hashCode() {
3218  5 int result = name.hashCode();
3219  5 result = 31 * result + methodName.hashCode();
3220  5 result = 31 * result + methodDescriptor.hashCode();
3221  5 return result;
3222    }
3223   
 
3224  5 toggle @Override
3225    public String toString() {
3226  5 return "TypePool.Default.LazyTypeDescription.DeclarationContext.DeclaredInMethod{" +
3227    "name='" + name + '\'' +
3228    ", methodName='" + methodName + '\'' +
3229    ", methodDescriptor='" + methodDescriptor + '\'' +
3230    '}';
3231    }
3232    }
3233    }
3234   
3235    /**
3236    * A token that represents a generic Java type.
3237    */
 
3238    protected interface GenericTypeToken {
3239   
3240    /**
3241    * Represents an empty type path.
3242    */
3243    String EMPTY_TYPE_PATH = "";
3244   
3245    /**
3246    * Represents a step to a component type within a type path.
3247    */
3248    char COMPONENT_TYPE_PATH = '[';
3249   
3250    /**
3251    * Represents a wildcard type step within a type path.
3252    */
3253    char WILDCARD_TYPE_PATH = '*';
3254   
3255    /**
3256    * Represents a (reversed) step to an inner class within a type path.
3257    */
3258    char INNER_CLASS_PATH = '.';
3259   
3260    /**
3261    * Represents an index type delimiter within a type path.
3262    */
3263    char INDEXED_TYPE_DELIMITER = ';';
3264   
3265    /**
3266    * Transforms this token into a generic type representation.
3267    *
3268    * @param typePool The type pool to be used for locating non-generic type descriptions.
3269    * @param typeVariableSource The type variable source.
3270    * @param typePath The type path of the resolved generic type.
3271    * @param annotationTokens A mapping of the type's annotation tokens by their type path.
3272    * @return A description of the represented generic type.
3273    */
3274    Generic toGenericType(TypePool typePool, TypeVariableSource typeVariableSource, String typePath, Map<String, List<AnnotationToken>> annotationTokens);
3275   
3276    /**
3277    * Determines if a generic type tokens represents a primary bound of a type variable. This method must only be invoked on types
3278    * that represent a {@link Sort#NON_GENERIC},
3279    * {@link Sort#PARAMETERIZED} or {@link Sort#VARIABLE}.
3280    *
3281    * @param typePool The type pool to use.
3282    * @return {@code true} if this token represents a primary bound.
3283    */
3284    boolean isPrimaryBound(TypePool typePool);
3285   
3286    /**
3287    * Returns the type path prefix that needs to be appended to the existing type path before any further navigation on the parameterized
3288    * type. This method must only be called on type tokens that represent parameterized type
3289    *
3290    * @return A type path segment that needs to be appended to the base type path before any further navigation on the parameterized type.
3291    */
3292    String getTypePathPrefix();
3293   
3294    /**
3295    * Represents a generic type token for a formal type variable.
3296    */
 
3297    interface OfFormalTypeVariable {
3298   
3299    /**
3300    * Transforms this token into a generic type representation.
3301    *
3302    * @param typePool The type pool to be used for locating non-generic type descriptions.
3303    * @param typeVariableSource The type variable source.
3304    * @param annotationTokens A mapping of the type variables' type annotations.
3305    * @param boundaryAnnotationTokens A mapping of the type variables' bounds' type annotation by their bound index.
3306    * @return A generic type representation of this formal type variable.
3307    */
3308    Generic toGenericType(TypePool typePool,
3309    TypeVariableSource typeVariableSource,
3310    Map<String, List<AnnotationToken>> annotationTokens,
3311    Map<Integer, Map<String, List<AnnotationToken>>> boundaryAnnotationTokens);
3312    }
3313   
3314    /**
3315    * A generic type token that represents a primitive type.
3316    */
 
3317    enum ForPrimitiveType implements GenericTypeToken {
3318   
3319    /**
3320    * The generic type token describing the {@code boolean} type.
3321    */
3322    BOOLEAN(boolean.class),
3323   
3324    /**
3325    * The generic type token describing the {@code byte} type.
3326    */
3327    BYTE(byte.class),
3328   
3329    /**
3330    * The generic type token describing the {@code short} type.
3331    */
3332    SHORT(short.class),
3333   
3334    /**
3335    * The generic type token describing the {@code char} type.
3336    */
3337    CHAR(char.class),
3338   
3339    /**
3340    * The generic type token describing the {@code int} type.
3341    */
3342    INTEGER(int.class),
3343   
3344    /**
3345    * The generic type token describing the {@code long} type.
3346    */
3347    LONG(long.class),
3348   
3349    /**
3350    * The generic type token describing the {@code float} type.
3351    */
3352    FLOAT(float.class),
3353   
3354    /**
3355    * The generic type token describing the {@code double} type.
3356    */
3357    DOUBLE(double.class),
3358   
3359    /**
3360    * The generic type token describing the {@code void} type.
3361    */
3362    VOID(void.class);
3363   
3364    /**
3365    * A description of this primitive type token.
3366    */
3367    private final TypeDescription typeDescription;
3368   
3369    /**
3370    * Creates a new primitive type token.
3371    *
3372    * @param type The loaded type representing this primitive.
3373    */
 
3374  9 toggle ForPrimitiveType(Class<?> type) {
3375  9 typeDescription = new ForLoadedType(type);
3376    }
3377   
3378    /**
3379    * Resolves a generic type token of a primitive type.
3380    *
3381    * @param descriptor The descriptor of the primitive type.
3382    * @return The corresponding generic type token.
3383    */
 
3384  7213 toggle public static GenericTypeToken of(char descriptor) {
3385  7213 switch (descriptor) {
3386  1666 case 'V':
3387  1666 return VOID;
3388  2615 case 'Z':
3389  2615 return BOOLEAN;
3390  0 case 'B':
3391  0 return BYTE;
3392  0 case 'S':
3393  0 return SHORT;
3394  0 case 'C':
3395  0 return CHAR;
3396  2932 case 'I':
3397  2932 return INTEGER;
3398  0 case 'J':
3399  0 return LONG;
3400  0 case 'F':
3401  0 return FLOAT;
3402  0 case 'D':
3403  0 return DOUBLE;
3404  0 default:
3405  0 throw new IllegalArgumentException("Not a valid primitive type descriptor: " + descriptor);
3406    }
3407    }
3408   
 
3409  20 toggle @Override
3410    public Generic toGenericType(TypePool typePool,
3411    TypeVariableSource typeVariableSource,
3412    String typePath,
3413    Map<String, List<AnnotationToken>> annotationTokens) {
3414  20 return new LazyPrimitiveType(typePool,
3415    typePath,
3416  20 annotationTokens == null
3417    ? Collections.<String, List<AnnotationToken>>emptyMap()
3418    : annotationTokens,
3419    typeDescription);
3420    }
3421   
 
3422  1 toggle @Override
3423    public boolean isPrimaryBound(TypePool typePool) {
3424  1 throw new IllegalStateException("A primitive type cannot be a type variable bound: " + this);
3425    }
3426   
 
3427  1 toggle @Override
3428    public String getTypePathPrefix() {
3429  1 throw new IllegalStateException("A primitive type cannot be the owner of a nested type: " + this);
3430    }
3431   
 
3432  11 toggle @Override
3433    public String toString() {
3434  11 return "TypePool.Default.LazyTypeDescription.GenericTypeToken.ForPrimitiveType." + name();
3435    }
3436   
3437    /**
3438    * A representation of a lazy primitive type.
3439    */
 
3440    protected static class LazyPrimitiveType extends Generic.OfNonGenericType {
3441   
3442    /**
3443    * The type pool to use.
3444    */
3445    private final TypePool typePool;
3446   
3447    /**
3448    * This type's type path.
3449    */
3450    private final String typePath;
3451   
3452    /**
3453    * This type's type annotation tokens.
3454    */
3455    private final Map<String, List<AnnotationToken>> annotationTokens;
3456   
3457    /**
3458    * The represented type's description.
3459    */
3460    private final TypeDescription typeDescription;
3461   
3462    /**
3463    * Creates a new lazy primitive type.
3464    *
3465    * @param typePool The type pool to use.
3466    * @param typePath This type's type path.
3467    * @param annotationTokens This type's type annotation tokens.
3468    * @param typeDescription The represented type's description.
3469    */
 
3470  20 toggle protected LazyPrimitiveType(TypePool typePool,
3471    String typePath,
3472    Map<String, List<AnnotationToken>> annotationTokens,
3473    TypeDescription typeDescription) {
3474  20 this.typePool = typePool;
3475  20 this.typePath = typePath;
3476  20 this.annotationTokens = annotationTokens;
3477  20 this.typeDescription = typeDescription;
3478    }
3479   
 
3480  0 toggle @Override
3481    public TypeDescription asErasure() {
3482  0 return typeDescription;
3483    }
3484   
 
3485  0 toggle @Override
3486    public Generic getOwnerType() {
3487  0 return UNDEFINED;
3488    }
3489   
 
3490  0 toggle @Override
3491    public Generic getComponentType() {
3492  0 return UNDEFINED;
3493    }
3494   
 
3495  12 toggle @Override
3496    public AnnotationList getDeclaredAnnotations() {
3497  12 return LazyAnnotationDescription.asListOfNullable(typePool, annotationTokens.get(typePath));
3498    }
3499    }
3500    }
3501   
3502    /**
3503    * A generic type token that represents an unbound wildcard.
3504    */
 
3505    enum ForUnboundWildcard implements GenericTypeToken {
3506   
3507    /**
3508    * The singleton instance.
3509    */
3510    INSTANCE;
3511   
 
3512  94 toggle @Override
3513    public Generic toGenericType(TypePool typePool,
3514    TypeVariableSource typeVariableSource,
3515    String typePath,
3516    Map<String, List<AnnotationToken>> annotationTokens) {
3517  94 return new LazyUnboundWildcard(typePool,
3518    typePath,
3519  94 annotationTokens == null
3520    ? Collections.<String, List<AnnotationToken>>emptyMap()
3521    : annotationTokens);
3522    }
3523   
 
3524  1 toggle @Override
3525    public boolean isPrimaryBound(TypePool typePool) {
3526  1 throw new IllegalStateException("A wildcard type cannot be a type variable bound: " + this);
3527    }
3528   
 
3529  1 toggle @Override
3530    public String getTypePathPrefix() {
3531  1 throw new IllegalStateException("An unbound wildcard cannot be the owner of a nested type: " + this);
3532    }
3533   
 
3534  3 toggle @Override
3535    public String toString() {
3536  3 return "TypePool.Default.LazyTypeDescription.GenericTypeToken.ForUnboundWildcard." + name();
3537    }
3538   
3539    /**
3540    * A generic type representation of a generic unbound wildcard.
3541    */
 
3542    protected static class LazyUnboundWildcard extends Generic.OfWildcardType {
3543   
3544    /**
3545    * The type pool to use.
3546    */
3547    private final TypePool typePool;
3548   
3549    /**
3550    * This type's type path.
3551    */
3552    private final String typePath;
3553   
3554    /**
3555    * The type's type annotations.
3556    */
3557    private final Map<String, List<AnnotationToken>> annotationTokens;
3558   
3559    /**
3560    * Creates a new lazy unbound wildcard.
3561    *
3562    * @param typePool The type pool to use.
3563    * @param typePath This type's type path.
3564    * @param annotationTokens The type's type annotations.
3565    */
 
3566  94 toggle protected LazyUnboundWildcard(TypePool typePool, String typePath, Map<String, List<AnnotationToken>> annotationTokens) {
3567  94 this.typePool = typePool;
3568  94 this.typePath = typePath;
3569  94 this.annotationTokens = annotationTokens;
3570    }
3571   
 
3572  76 toggle @Override
3573    public TypeList.Generic getUpperBounds() {
3574  76 return new TypeList.Generic.Explicit(Generic.OBJECT);
3575    }
3576   
 
3577  72 toggle @Override
3578    public TypeList.Generic getLowerBounds() {
3579  72 return new TypeList.Generic.Empty();
3580    }
3581   
 
3582  42 toggle @Override
3583    public AnnotationList getDeclaredAnnotations() {
3584  42 return LazyAnnotationDescription.asListOfNullable(typePool, annotationTokens.get(typePath));
3585    }
3586    }
3587    }
3588   
3589    /**
3590    * A resolution of a type's, method's or field's generic types.
3591    */
 
3592    interface Resolution {
3593   
3594    /**
3595    * Resolves the type variables of the represented element.
3596    *
3597    * @param typePool The type pool to be used for locating non-generic type descriptions.
3598    * @param typeVariableSource The type variable source to use for resolving type variables.
3599    * @param annotationTokens A mapping of the type variables' type annotation tokens by their indices.
3600    * @param boundAnnotationTokens A mapping of the type variables' bounds' type annotation tokens by their indices
3601    * and each type variable's index.
3602    * @return A list describing the resolved generic types.
3603    */
3604    TypeList.Generic resolveTypeVariables(TypePool typePool,
3605    TypeVariableSource typeVariableSource,
3606    Map<Integer, Map<String, List<AnnotationToken>>> annotationTokens,
3607    Map<Integer, Map<Integer, Map<String, List<AnnotationToken>>>> boundAnnotationTokens);
3608   
3609    /**
3610    * A resolution of a type's, method's or field's generic types if all of the represented element's are raw.
3611    */
 
3612    enum Raw implements ForType, ForMethod, ForField {
3613   
3614    /**
3615    * The singleton instance.
3616    */
3617    INSTANCE;
3618   
 
3619  69 toggle @Override
3620    public Generic resolveFieldType(String fieldTypeDescriptor,
3621    TypePool typePool,
3622    Map<String, List<AnnotationToken>> annotationTokens,
3623    FieldDescription.InDefinedShape definingField) {
3624  69 return RawAnnotatedType.of(typePool, annotationTokens, fieldTypeDescriptor);
3625    }
3626   
 
3627  1801 toggle @Override
3628    public Generic resolveReturnType(String returnTypeDescriptor,
3629    TypePool typePool,
3630    Map<String, List<AnnotationToken>> annotationTokens,
3631    MethodDescription.InDefinedShape definingMethod) {
3632  1801 return RawAnnotatedType.of(typePool, annotationTokens, returnTypeDescriptor);
3633    }
3634   
 
3635  1037 toggle @Override
3636    public TypeList.Generic resolveParameterTypes(List<String> parameterTypeDescriptors,
3637    TypePool typePool,
3638    Map<Integer, Map<String, List<AnnotationToken>>> annotationTokens,
3639    MethodDescription.InDefinedShape definingMethod) {
3640  1037 return RawAnnotatedType.LazyRawAnnotatedTypeList.of(typePool, annotationTokens, parameterTypeDescriptors);
3641    }
3642   
 
3643  437 toggle @Override
3644    public TypeList.Generic resolveExceptionTypes(List<String> exceptionTypeDescriptors,
3645    TypePool typePool,
3646    Map<Integer, Map<String, List<AnnotationToken>>> annotationTokens,
3647    MethodDescription.InDefinedShape definingMethod) {
3648  437 return RawAnnotatedType.LazyRawAnnotatedTypeList.of(typePool, annotationTokens, exceptionTypeDescriptors);
3649    }
3650   
 
3651  239 toggle @Override
3652    public Generic resolveSuperClass(String superClassDescriptor,
3653    TypePool typePool,
3654    Map<String, List<AnnotationToken>> annotationTokens,
3655    TypeDescription definingType) {
3656  239 return RawAnnotatedType.of(typePool, annotationTokens, superClassDescriptor);
3657    }
3658   
 
3659  511 toggle @Override
3660    public TypeList.Generic resolveInterfaceTypes(List<String> interfaceTypeDescriptors,
3661    TypePool typePool,
3662    Map<Integer, Map<String, List<AnnotationToken>>> annotationTokens,
3663    TypeDescription definingType) {
3664  511 return RawAnnotatedType.LazyRawAnnotatedTypeList.of(typePool, annotationTokens, interfaceTypeDescriptors);
3665    }
3666   
 
3667  914 toggle @Override
3668    public TypeList.Generic resolveTypeVariables(TypePool typePool,
3669    TypeVariableSource typeVariableSource,
3670    Map<Integer, Map<String, List<AnnotationToken>>> annotationTokens,
3671    Map<Integer, Map<Integer, Map<String, List<AnnotationToken>>>> boundAnnotationTokens) {
3672  914 return new TypeList.Generic.Empty();
3673    }
3674   
 
3675  1 toggle @Override
3676    public String toString() {
3677  1 return "TypePool.Default.LazyTypeDescription.GenericTypeToken.Resolution.Raw." + name();
3678    }
3679   
3680    /**
3681    * Represents a non-generic type that defines type annotations.
3682    */
 
3683    protected static class RawAnnotatedType extends Generic.OfNonGenericType {
3684   
3685    /**
3686    * The type pool to use.
3687    */
3688    private final TypePool typePool;
3689   
3690    /**
3691    * The type's type path.
3692    */
3693    private final String typePath;
3694   
3695    /**
3696    * A mapping of this type's type annotations.
3697    */
3698    private final Map<String, List<AnnotationToken>> annotationTokens;
3699   
3700    /**
3701    * The represented non-generic type.
3702    */
3703    private final TypeDescription typeDescription;
3704   
3705    /**
3706    * Creates a new raw annotated type.
3707    *
3708    * @param typePool The type pool to use.
3709    * @param typePath The type's type path.
3710    * @param annotationTokens A mapping of this type's type annotations.
3711    * @param typeDescription The represented non-generic type.
3712    */
 
3713  3120 toggle protected RawAnnotatedType(TypePool typePool,
3714    String typePath,
3715    Map<String, List<AnnotationToken>> annotationTokens,
3716    TypeDescription typeDescription) {
3717  3120 this.typePool = typePool;
3718  3120 this.typePath = typePath;
3719  3120 this.annotationTokens = annotationTokens;
3720  3120 this.typeDescription = typeDescription;
3721    }
3722   
3723    /**
3724    * Creates a new raw annotated type.
3725    *
3726    * @param typePool The type pool to use.
3727    * @param annotationTokens A mapping of this type's type annotations.
3728    * @param descriptor The descriptor of the represented non-generic type.
3729    * @return An annotated non-generic type.
3730    */
 
3731  2429 toggle protected static Generic of(TypePool typePool, Map<String, List<AnnotationToken>> annotationTokens, String descriptor) {
3732  2429 return new RawAnnotatedType(typePool,
3733    EMPTY_TYPE_PATH,
3734  2429 annotationTokens == null
3735    ? Collections.<String, List<AnnotationToken>>emptyMap()
3736    : annotationTokens,
3737    TokenizedGenericType.toErasure(typePool, descriptor));
3738    }
3739   
 
3740  26430 toggle @Override
3741    public TypeDescription asErasure() {
3742  26430 return typeDescription;
3743    }
3744   
 
3745  12 toggle @Override
3746    public Generic getOwnerType() {
3747  12 TypeDescription declaringType = typeDescription.getDeclaringType();
3748  12 return declaringType == null
3749    ? UNDEFINED
3750    : new RawAnnotatedType(typePool, typePath, annotationTokens, declaringType);
3751    }
3752   
 
3753  48 toggle @Override
3754    public Generic getComponentType() {
3755  48 TypeDescription componentType = typeDescription.getComponentType();
3756  48 return componentType == null
3757    ? UNDEFINED
3758    : new RawAnnotatedType(typePool, typePath + COMPONENT_TYPE_PATH, annotationTokens, componentType);
3759    }
3760   
 
3761  576 toggle @Override
3762    public AnnotationList getDeclaredAnnotations() {
3763  576 StringBuilder typePath = new StringBuilder(this.typePath);
3764  582 for (int index = 0; index < typeDescription.getSegmentCount(); index++) {
3765  6 typePath = typePath.append(INNER_CLASS_PATH);
3766    }
3767  576 return LazyAnnotationDescription.asListOfNullable(typePool, annotationTokens.get(typePath.toString()));
3768    }
3769   
3770    /**
3771    * A generic type list representing raw types.
3772    */
 
3773    protected static class LazyRawAnnotatedTypeList extends TypeList.Generic.AbstractBase {
3774   
3775    /**
3776    * The type pool to use for locating types.
3777    */
3778    private final TypePool typePool;
3779   
3780    /**
3781    * A mapping of the represented types' type annotation tokens by their indices.
3782    */
3783    private final Map<Integer, Map<String, List<AnnotationToken>>> annotationTokens;
3784   
3785    /**
3786    * A list of type descriptors that this list represents.
3787    */
3788    private final List<String> descriptors;
3789   
3790    /**
3791    * Creates a generic type list only representing raw types.
3792    *
3793    * @param typePool The type pool to use for locating types.
3794    * @param annotationTokens A mapping of the represented types' type annotation tokens by their indices.
3795    * @param descriptors A list of type descriptors that this list represents.
3796    */
 
3797  1985 toggle protected LazyRawAnnotatedTypeList(TypePool typePool,
3798    Map<Integer, Map<String, List<AnnotationToken>>> annotationTokens,
3799    List<String> descriptors) {
3800  1985 this.typePool = typePool;
3801  1985 this.annotationTokens = annotationTokens;
3802  1985 this.descriptors = descriptors;
3803    }
3804   
3805    /**
3806    * Creates generic type list only representing raw types.
3807    *
3808    * @param typePool The type pool to use for locating types.
3809    * @param annotationTokens A mapping of the represented types' type annotation tokens by their indices or
3810    * {@code null} if no type annotations are defined for any type.
3811    * @param descriptors A list of type descriptors that this list represents.
3812    * @return A generic type list representing the raw types this list represents.
3813    */
 
3814  1985 toggle protected static TypeList.Generic of(TypePool typePool,
3815    Map<Integer, Map<String, List<AnnotationToken>>> annotationTokens,
3816    List<String> descriptors) {
3817  1985 return new LazyRawAnnotatedTypeList(typePool,
3818  1985 annotationTokens == null
3819    ? Collections.<Integer, Map<String, List<AnnotationToken>>>emptyMap()
3820    : annotationTokens,
3821    descriptors);
3822    }
3823   
 
3824  320 toggle @Override
3825    public Generic get(int index) {
3826  320 return RawAnnotatedType.of(typePool, annotationTokens.get(index), descriptors.get(index));
3827    }
3828   
 
3829  1275 toggle @Override
3830    public int size() {
3831  1275 return descriptors.size();
3832    }
3833   
 
3834  1155 toggle @Override
3835    public TypeList asErasures() {
3836  1155 return new LazyTypeList(typePool, descriptors);
3837    }
3838   
 
3839  0 toggle @Override
3840    public TypeList.Generic asRawTypes() {
3841  0 return this;
3842    }
3843   
 
3844  0 toggle @Override
3845    public int getStackSize() {
3846  0 int stackSize = 0;
3847  0 for (String descriptor : descriptors) {
3848  0 stackSize += Type.getType(descriptor).getSize();
3849    }
3850  0 return stackSize;
3851    }
3852    }
3853    }
3854    }
3855   
3856    /**
3857    * A resolution of a type's, method's or field's generic types if its generic signature is malformed.
3858    */
 
3859    enum Malformed implements ForType, ForMethod, ForField {
3860   
3861    /**
3862    * The singleton instance.
3863    */
3864    INSTANCE;
3865   
 
3866  2 toggle @Override
3867    public Generic resolveFieldType(String fieldTypeDescriptor,
3868    TypePool typePool,
3869    Map<String, List<AnnotationToken>> annotationTokens,
3870    FieldDescription.InDefinedShape definingField) {
3871  2 return new TokenizedGenericType.Malformed(typePool, fieldTypeDescriptor);
3872    }
3873   
 
3874  2 toggle @Override
3875    public Generic resolveReturnType(String returnTypeDescriptor,
3876    TypePool typePool,
3877    Map<String, List<AnnotationToken>> annotationTokens,
3878    MethodDescription.InDefinedShape definingMethod) {
3879  2 return new TokenizedGenericType.Malformed(typePool, returnTypeDescriptor);
3880    }
3881   
 
3882  0 toggle @Override
3883    public TypeList.Generic resolveParameterTypes(List<String> parameterTypeDescriptors,
3884    TypePool typePool,
3885    Map<Integer, Map<String, List<AnnotationToken>>> annotationTokens,
3886    MethodDescription.InDefinedShape definingMethod) {
3887  0 return new TokenizedGenericType.Malformed.TokenList(typePool, parameterTypeDescriptors);
3888    }
3889   
 
3890  0 toggle @Override
3891    public TypeList.Generic resolveExceptionTypes(List<String> exceptionTypeDescriptors,
3892    TypePool typePool,
3893    Map<Integer, Map<String, List<AnnotationToken>>> annotationTokens,
3894    MethodDescription.InDefinedShape definingMethod) {
3895  0 return new TokenizedGenericType.Malformed.TokenList(typePool, exceptionTypeDescriptors);
3896    }
3897   
 
3898  0 toggle @Override
3899    public Generic resolveSuperClass(String superClassDescriptor,
3900    TypePool typePool,
3901    Map<String, List<AnnotationToken>> annotationTokens,
3902    TypeDescription definingType) {
3903  0 return new TokenizedGenericType.Malformed(typePool, superClassDescriptor);
3904    }
3905   
 
3906  4 toggle @Override
3907    public TypeList.Generic resolveInterfaceTypes(List<String> interfaceTypeDescriptors,
3908    TypePool typePool,
3909    Map<Integer, Map<String, List<AnnotationToken>>> annotationTokens,
3910    TypeDescription definingType) {
3911  4 return new TokenizedGenericType.Malformed.TokenList(typePool, interfaceTypeDescriptors);
3912    }
3913   
 
3914  0 toggle @Override
3915    public TypeList.Generic resolveTypeVariables(TypePool typePool,
3916    TypeVariableSource typeVariableSource,
3917    Map<Integer, Map<String, List<AnnotationToken>>> annotationTokens,
3918    Map<Integer, Map<Integer, Map<String, List<AnnotationToken>>>> boundAnnotationTokens) {
3919  0 throw new GenericSignatureFormatError();
3920    }
3921   
 
3922  1 toggle @Override
3923    public String toString() {
3924  1 return "TypePool.Default.LazyTypeDescription.GenericTypeToken.Resolution.Malformed." + name();
3925    }
3926    }
3927   
3928    /**
3929    * A resolution of the generic types of a {@link TypeDescription}.
3930    */
 
3931    interface ForType extends Resolution {
3932   
3933    /**
3934    * Resolves the generic super type of the represented type.
3935    *
3936    * @param superClassDescriptor The descriptor of the raw super type.
3937    * @param typePool The type pool to be used for locating non-generic type descriptions.
3938    * @param annotationTokens A mapping of the super type's type annotation tokens.
3939    * @param definingType The type that defines this super type.
3940    * @return A description of this type's generic super type.
3941    */
3942    Generic resolveSuperClass(String superClassDescriptor,
3943    TypePool typePool,
3944    Map<String, List<AnnotationToken>> annotationTokens,
3945    TypeDescription definingType);
3946   
3947    /**
3948    * Resolves the generic interface types of the represented type.
3949    *
3950    * @param interfaceTypeDescriptors The descriptor of the raw interface types.
3951    * @param typePool The type pool to be used for locating non-generic type descriptions.
3952    * @param annotationTokens A mapping of the interface types' type annotation tokens by their indices.
3953    * @param definingType The type that defines these interface type.
3954    * @return A description of this type's generic interface types.
3955    */
3956    TypeList.Generic resolveInterfaceTypes(List<String> interfaceTypeDescriptors,
3957    TypePool typePool,
3958    Map<Integer, Map<String, List<AnnotationToken>>> annotationTokens,
3959    TypeDescription definingType);
3960   
3961    /**
3962    * An implementation of a tokenized resolution of generic types of a {@link TypeDescription}.
3963    */
 
3964    class Tokenized implements ForType {
3965   
3966    /**
3967    * The super type's generic type token.
3968    */
3969    private final GenericTypeToken superClassToken;
3970   
3971    /**
3972    * The interface type's generic type tokens.
3973    */
3974    private final List<GenericTypeToken> interfaceTypeTokens;
3975   
3976    /**
3977    * The type variables generic type tokens.
3978    */
3979    private final List<OfFormalTypeVariable> typeVariableTokens;
3980   
3981    /**
3982    * Creates a new tokenized resolution of a {@link TypeDescription}'s generic signatures.
3983    *
3984    * @param superClassToken The super class's generic type token.
3985    * @param interfaceTypeTokens The interface type's generic type tokens.
3986    * @param typeVariableTokens The type variables generic type tokens.
3987    */
 
3988  1926 toggle public Tokenized(GenericTypeToken superClassToken,
3989    List<GenericTypeToken> interfaceTypeTokens,
3990    List<OfFormalTypeVariable> typeVariableTokens) {
3991  1926 this.superClassToken = superClassToken;
3992  1926 this.interfaceTypeTokens = interfaceTypeTokens;
3993  1926 this.typeVariableTokens = typeVariableTokens;
3994    }
3995   
 
3996  221 toggle @Override
3997    public Generic resolveSuperClass(String superClassDescriptor,
3998    TypePool typePool,
3999    Map<String, List<AnnotationToken>> annotationTokens,
4000    TypeDescription definingType) {
4001  221 return TokenizedGenericType.of(typePool, superClassToken, superClassDescriptor, annotationTokens, definingType);
4002    }
4003   
 
4004  244 toggle @Override
4005    public TypeList.Generic resolveInterfaceTypes(List<String> interfaceTypeDescriptors,
4006    TypePool typePool,
4007    Map<Integer, Map<String, List<AnnotationToken>>> annotationTokens,
4008    TypeDescription definingType) {
4009  244 return new TokenizedGenericType.TokenList(typePool, interfaceTypeTokens, annotationTokens, interfaceTypeDescriptors, definingType);
4010    }
4011   
 
4012  986 toggle @Override
4013    public TypeList.Generic resolveTypeVariables(TypePool typePool,
4014    TypeVariableSource typeVariableSource,
4015    Map<Integer, Map<String, List<AnnotationToken>>> annotationTokens,
4016    Map<Integer, Map<Integer, Map<String, List<AnnotationToken>>>> boundAnnotationTokens) {
4017  986 return new TokenizedGenericType.TypeVariableList(typePool, typeVariableTokens, typeVariableSource, annotationTokens, boundAnnotationTokens);
4018    }
4019   
 
4020  7 toggle @Override
4021    public boolean equals(Object other) {
4022  1 if (this == other) return true;
4023  2 if (other == null || getClass() != other.getClass()) return false;
4024  4 Tokenized tokenized = (Tokenized) other;
4025  4 return superClassToken.equals(tokenized.superClassToken)
4026    && interfaceTypeTokens.equals(tokenized.interfaceTypeTokens)
4027    && typeVariableTokens.equals(tokenized.typeVariableTokens);
4028    }
4029   
 
4030  5 toggle @Override
4031    public int hashCode() {
4032  5 int result = superClassToken.hashCode();
4033  5 result = 31 * result + interfaceTypeTokens.hashCode();
4034  5 result = 31 * result + typeVariableTokens.hashCode();
4035  5 return result;
4036    }
4037   
 
4038  5 toggle @Override
4039    public String toString() {
4040  5 return "TypePool.Default.LazyTypeDescription.GenericTypeToken.Resolution.ForType.Tokenized{" +
4041    "superClassToken=" + superClassToken +
4042    ", interfaceTypeTokens=" + interfaceTypeTokens +
4043    ", typeVariableTokens=" + typeVariableTokens +
4044    '}';
4045    }
4046    }
4047    }
4048   
4049    /**
4050    * A resolution of the generic types of a {@link MethodDescription}.
4051    */
 
4052    interface ForMethod extends Resolution {
4053   
4054    /**
4055    * Resolves the return type of the represented method.
4056    *
4057    * @param returnTypeDescriptor The descriptor of the raw return type.
4058    * @param typePool The type pool to be used for locating non-generic type descriptions.
4059    * @param annotationTokens A mapping of the return type's type annotation tokens.
4060    * @param definingMethod The method that defines this return type.
4061    * @return A description of this type's generic return type.
4062    */
4063    Generic resolveReturnType(String returnTypeDescriptor,
4064    TypePool typePool,
4065    Map<String, List<AnnotationToken>> annotationTokens,
4066    MethodDescription.InDefinedShape definingMethod);
4067   
4068    /**
4069    * Resolves the generic parameter types of the represented method.
4070    *
4071    * @param parameterTypeDescriptors The descriptor of the raw parameter types.
4072    * @param typePool The type pool to be used for locating non-generic type descriptions.
4073    * @param annotationTokens A mapping of the parameter types' type annotation tokens by their indices.
4074    * @param definingMethod The method that defines these parameter types.
4075    * @return A description of this type's generic interface types.
4076    */
4077    TypeList.Generic resolveParameterTypes(List<String> parameterTypeDescriptors,
4078    TypePool typePool,
4079    Map<Integer, Map<String, List<AnnotationToken>>> annotationTokens,
4080    MethodDescription.InDefinedShape definingMethod);
4081   
4082    /**
4083    * Resolves the generic parameter types of the represented method.
4084    *
4085    * @param exceptionTypeDescriptors The descriptor of the raw exception types.
4086    * @param typePool The type pool to be used for locating non-generic type descriptions.
4087    * @param annotationTokens A mapping of the exception types' type annotation tokens by their indices.
4088    * @param definingMethod The method that defines these exception types.
4089    * @return A description of this type's generic interface types.
4090    */
4091    TypeList.Generic resolveExceptionTypes(List<String> exceptionTypeDescriptors,
4092    TypePool typePool,
4093    Map<Integer, Map<String, List<AnnotationToken>>> annotationTokens,
4094    MethodDescription.InDefinedShape definingMethod);
4095   
4096    /**
4097    * An implementation of a tokenized resolution of generic types of a {@link MethodDescription}.
4098    */
 
4099    class Tokenized implements ForMethod {
4100   
4101    /**
4102    * A token describing the represented method's return type.
4103    */
4104    private final GenericTypeToken returnTypeToken;
4105   
4106    /**
4107    * A token describing the represented method's parameter types.
4108    */
4109    private final List<GenericTypeToken> parameterTypeTokens;
4110   
4111    /**
4112    * A token describing the represented method's exception types.
4113    */
4114    private final List<GenericTypeToken> exceptionTypeTokens;
4115   
4116    /**
4117    * A token describing the represented method's type variables.
4118    */
4119    private final List<OfFormalTypeVariable> typeVariableTokens;
4120   
4121    /**
4122    * Creates a new tokenized resolution of a {@link MethodDescription}'s generic signatures.
4123    *
4124    * @param returnTypeToken A token describing the represented method's return type.
4125    * @param parameterTypeTokens A token describing the represented method's parameter types.
4126    * @param exceptionTypeTokens A token describing the represented method's exception types.
4127    * @param typeVariableTokens A token describing the represented method's type variables.
4128    */
 
4129  12523 toggle public Tokenized(GenericTypeToken returnTypeToken,
4130    List<GenericTypeToken> parameterTypeTokens,
4131    List<GenericTypeToken> exceptionTypeTokens,
4132    List<OfFormalTypeVariable> typeVariableTokens) {
4133  12523 this.returnTypeToken = returnTypeToken;
4134  12523 this.parameterTypeTokens = parameterTypeTokens;
4135  12523 this.exceptionTypeTokens = exceptionTypeTokens;
4136  12523 this.typeVariableTokens = typeVariableTokens;
4137    }
4138   
 
4139  546 toggle @Override
4140    public Generic resolveReturnType(String returnTypeDescriptor,
4141    TypePool typePool,
4142    Map<String, List<AnnotationToken>> annotationTokens,
4143    MethodDescription.InDefinedShape definingMethod) {
4144  546 return TokenizedGenericType.of(typePool, returnTypeToken, returnTypeDescriptor, annotationTokens, definingMethod);
4145    }
4146   
 
4147  318 toggle @Override
4148    public TypeList.Generic resolveParameterTypes(List<String> parameterTypeDescriptors,
4149    TypePool typePool,
4150    Map<Integer, Map<String, List<AnnotationToken>>> annotationTokens,
4151    MethodDescription.InDefinedShape definingMethod) {
4152  318 return new TokenizedGenericType.TokenList(typePool, parameterTypeTokens, annotationTokens, parameterTypeDescriptors, definingMethod);
4153    }
4154   
 
4155  27 toggle @Override
4156    public TypeList.Generic resolveExceptionTypes(List<String> exceptionTypeDescriptors,
4157    TypePool typePool,
4158    Map<Integer, Map<String, List<AnnotationToken>>> annotationTokens,
4159    MethodDescription.InDefinedShape definingMethod) {
4160    // Generic signatures of methods are optional.
4161  27 return exceptionTypeTokens.isEmpty()
4162    ? Raw.INSTANCE.resolveExceptionTypes(exceptionTypeDescriptors, typePool, annotationTokens, definingMethod)
4163    : new TokenizedGenericType.TokenList(typePool, exceptionTypeTokens, annotationTokens, exceptionTypeDescriptors, definingMethod);
4164    }
4165   
 
4166  617 toggle @Override
4167    public TypeList.Generic resolveTypeVariables(TypePool typePool,
4168    TypeVariableSource typeVariableSource,
4169    Map<Integer, Map<String, List<AnnotationToken>>> annotationTokens,
4170    Map<Integer, Map<Integer, Map<String, List<AnnotationToken>>>> boundAnnotationTokens) {
4171  617 return new TokenizedGenericType.TypeVariableList(typePool, typeVariableTokens, typeVariableSource, annotationTokens, boundAnnotationTokens);
4172    }
4173   
 
4174  8 toggle @Override
4175    public boolean equals(Object other) {
4176  1 if (this == other) return true;
4177  2 if (other == null || getClass() != other.getClass()) return false;
4178  5 Tokenized tokenized = (Tokenized) other;
4179  5 return returnTypeToken.equals(tokenized.returnTypeToken)
4180    && parameterTypeTokens.equals(tokenized.parameterTypeTokens)
4181    && exceptionTypeTokens.equals(tokenized.exceptionTypeTokens)
4182    && typeVariableTokens.equals(tokenized.typeVariableTokens);
4183    }
4184   
 
4185  6 toggle @Override
4186    public int hashCode() {
4187  6 int result = returnTypeToken.hashCode();
4188  6 result = 31 * result + parameterTypeTokens.hashCode();
4189  6 result = 31 * result + exceptionTypeTokens.hashCode();
4190  6 result = 31 * result + typeVariableTokens.hashCode();
4191  6 return result;
4192    }
4193   
 
4194  6 toggle @Override
4195    public String toString() {
4196  6 return "TypePool.Default.LazyTypeDescription.GenericTypeToken.Resolution.ForMethod.Tokenized{" +
4197    "returnTypeToken=" + returnTypeToken +
4198    ", parameterTypeTokens=" + parameterTypeTokens +
4199    ", exceptionTypeTokens=" + exceptionTypeTokens +
4200    ", typeVariableTokens=" + typeVariableTokens +
4201    '}';
4202    }
4203    }
4204    }
4205   
4206    /**
4207    * A resolution of the generic types of a {@link FieldDescription}.
4208    */
 
4209    interface ForField {
4210   
4211    /**
4212    * Resolves the field type of the represented field.
4213    *
4214    * @param fieldTypeDescriptor The descriptor of the raw field type.
4215    * @param annotationTokens A mapping of the represented types' type annotation tokens.
4216    * @param typePool The type pool to be used for locating non-generic type descriptions.
4217    * @param definingField The field that defines this type. @return A description of this field's type.
4218    * @return A generic type representation of the field's type.
4219    */
4220    Generic resolveFieldType(String fieldTypeDescriptor,
4221    TypePool typePool,
4222    Map<String, List<AnnotationToken>> annotationTokens,
4223    FieldDescription.InDefinedShape definingField);
4224   
4225    /**
4226    * An implementation of a tokenized resolution of the generic type of a {@link FieldDescription}.
4227    */
 
4228    class Tokenized implements ForField {
4229   
4230    /**
4231    * The token of the represented field's type.
4232    */
4233    private final GenericTypeToken fieldTypeToken;
4234   
4235    /**
4236    * Creates a new tokenized resolution of a {@link FieldDescription}'s type.
4237    *
4238    * @param fieldTypeToken The token of the represented field's type.
4239    */
 
4240  2122 toggle public Tokenized(GenericTypeToken fieldTypeToken) {
4241  2122 this.fieldTypeToken = fieldTypeToken;
4242    }
4243   
 
4244  229 toggle @Override
4245    public Generic resolveFieldType(String fieldTypeDescriptor,
4246    TypePool typePool,
4247    Map<String, List<AnnotationToken>> annotationTokens,
4248    FieldDescription.InDefinedShape definingField) {
4249  229 return TokenizedGenericType.of(typePool, fieldTypeToken, fieldTypeDescriptor, annotationTokens, definingField.getDeclaringType());
4250    }
4251   
 
4252  5 toggle @Override
4253    public boolean equals(Object other) {
4254  5 return this == other || other != null && getClass() == other.getClass()
4255    && fieldTypeToken.equals(((Tokenized) other).fieldTypeToken);
4256    }
4257   
 
4258  3 toggle @Override
4259    public int hashCode() {
4260  3 return fieldTypeToken.hashCode();
4261    }
4262   
 
4263  3 toggle @Override
4264    public String toString() {
4265  3 return "TypePool.Default.LazyTypeDescription.GenericTypeToken.Resolution.ForField.Tokenized{" +
4266    "fieldTypeToken=" + fieldTypeToken +
4267    '}';
4268    }
4269    }
4270    }
4271    }
4272   
4273    /**
4274    * A generic type token that represents a non-generic type.
4275    */
 
4276    class ForRawType implements GenericTypeToken {
4277   
4278    /**
4279    * The name of the represented type.
4280    */
4281    private final String name;
4282   
4283    /**
4284    * Creates a new type token that represents a non-generic type.
4285    *
4286    * @param name The name of the represented type.
4287    */
 
4288  12932 toggle public ForRawType(String name) {
4289  12932 this.name = name;
4290    }
4291   
 
4292  633 toggle @Override
4293    public Generic toGenericType(TypePool typePool,
4294    TypeVariableSource typeVariableSource,
4295    String typePath,
4296    Map<String, List<AnnotationToken>> annotationTokens) {
4297  633 return new Resolution.Raw.RawAnnotatedType(typePool,
4298    typePath,
4299  633 annotationTokens == null
4300    ? Collections.<String, List<AnnotationToken>>emptyMap()
4301    : annotationTokens,
4302    typePool.describe(name).resolve());
4303    }
4304   
 
4305  204 toggle @Override
4306    public boolean isPrimaryBound(TypePool typePool) {
4307  204 return !typePool.describe(name).resolve().isInterface();
4308    }
4309   
 
4310  1 toggle @Override
4311    public String getTypePathPrefix() {
4312  1 throw new IllegalStateException("A non-generic type cannot be the owner of a nested type: " + this);
4313    }
4314   
 
4315  5 toggle @Override
4316    public boolean equals(Object other) {
4317  5 return this == other || !(other == null || getClass() != other.getClass()) && name.equals(((ForRawType) other).name);
4318    }
4319   
 
4320  3 toggle @Override
4321    public int hashCode() {
4322  3 return name.hashCode();
4323    }
4324   
 
4325  4 toggle @Override
4326    public String toString() {
4327  4 return "TypePool.Default.LazyTypeDescription.GenericTypeToken.ForRawType{" +
4328    "name='" + name + '\'' +
4329    '}';
4330    }
4331    }
4332   
4333    /**
4334    * A generic type token that represents a type variable.
4335    */
 
4336    class ForTypeVariable implements GenericTypeToken {
4337   
4338    /**
4339    * This type variable's nominal symbol.
4340    */
4341    private final String symbol;
4342   
4343    /**
4344    * Creates a generic type token that represents a type variable.
4345    *
4346    * @param symbol This type variable's nominal symbol.
4347    */
 
4348  13185 toggle public ForTypeVariable(String symbol) {
4349  13185 this.symbol = symbol;
4350    }
4351   
 
4352  892 toggle @Override
4353    public Generic toGenericType(TypePool typePool, TypeVariableSource typeVariableSource, String typePath, Map<String, List<AnnotationToken>> annotationTokens) {
4354  892 Generic typeVariable = typeVariableSource.findVariable(symbol);
4355  892 if (typeVariable == null) {
4356  0 throw new IllegalStateException("Cannot resolve type variable '" + symbol + "' for " + typeVariableSource);
4357    } else {
4358  892 return new AnnotatedTypeVariable(typePool, annotationTokens.get(typePath), typeVariable);
4359    }
4360    }
4361   
 
4362  32 toggle @Override
4363    public boolean isPrimaryBound(TypePool typePool) {
4364  32 return true;
4365    }
4366   
 
4367  1 toggle @Override
4368    public String getTypePathPrefix() {
4369  1 throw new IllegalStateException("A type variable cannot be the owner of a nested type: " + this);
4370    }
4371   
 
4372  5 toggle @Override
4373    public boolean equals(Object other) {
4374  5 return this == other || !(other == null || getClass() != other.getClass()) && symbol.equals(((ForTypeVariable) other).symbol);
4375    }
4376   
 
4377  3 toggle @Override
4378    public int hashCode() {
4379  3 return symbol.hashCode();
4380    }
4381   
 
4382  4 toggle @Override
4383    public String toString() {
4384  4 return "TypePool.Default.LazyTypeDescription.GenericTypeToken.ForTypeVariable{" +
4385    "symbol='" + symbol + '\'' +
4386    '}';
4387    }
4388   
4389    /**
4390    * An annotated representation of a formal type variable.
4391    */
 
4392    protected static class AnnotatedTypeVariable extends Generic.OfTypeVariable {
4393   
4394    /**
4395    * The type pool to use.
4396    */
4397    private final TypePool typePool;
4398   
4399    /**
4400    * The represented annotation tokens.
4401    */
4402    private final List<AnnotationToken> annotationTokens;
4403   
4404    /**
4405    * The represented type variable.
4406    */
4407    private final Generic typeVariable;
4408   
4409    /**
4410    * Creates a new annotated type variable.
4411    *
4412    * @param typePool The type pool to use.
4413    * @param annotationTokens The represented annotation tokens.
4414    * @param typeVariable The represented type variable.
4415    */
 
4416  892 toggle protected AnnotatedTypeVariable(TypePool typePool, List<AnnotationToken> annotationTokens, Generic typeVariable) {
4417  892 this.typePool = typePool;
4418  892 this.annotationTokens = annotationTokens;
4419  892 this.typeVariable = typeVariable;
4420    }
4421   
 
4422  214 toggle @Override
4423    public TypeList.Generic getUpperBounds() {
4424  214 return typeVariable.getUpperBounds();
4425    }
4426   
 
4427  443 toggle @Override
4428    public TypeVariableSource getVariableSource() {
4429  443 return typeVariable.getVariableSource();
4430    }
4431   
 
4432  260 toggle @Override
4433    public String getSymbol() {
4434  260 return typeVariable.getSymbol();
4435    }
4436   
 
4437  138 toggle @Override
4438    public AnnotationList getDeclaredAnnotations() {
4439  138 return LazyAnnotationDescription.asListOfNullable(typePool, annotationTokens);
4440    }
4441    }
4442   
4443    /**
4444    * A generic type token that represent a formal type variable, i.e. a type variable including its upper bounds.
4445    */
 
4446    public static class Formal implements GenericTypeToken.OfFormalTypeVariable {
4447   
4448    /**
4449    * This type variable's nominal symbol.
4450    */
4451    private final String symbol;
4452   
4453    /**
4454    * A list of tokens that represent this type variable's upper bounds.
4455    */
4456    private final List<GenericTypeToken> boundTypeTokens;
4457   
4458    /**
4459    * Creates generic type token that represent a formal type variable.
4460    *
4461    * @param symbol This type variable's nominal symbol.
4462    * @param boundTypeTokens A list of tokens that represent this type variable's upper bounds.
4463    */
 
4464  3173 toggle public Formal(String symbol, List<GenericTypeToken> boundTypeTokens) {
4465  3173 this.symbol = symbol;
4466  3173 this.boundTypeTokens = boundTypeTokens;
4467    }
4468   
 
4469  2544 toggle @Override
4470    public Generic toGenericType(TypePool typePool,
4471    TypeVariableSource typeVariableSource,
4472    Map<String, List<AnnotationToken>> annotationTokens,
4473    Map<Integer, Map<String, List<AnnotationToken>>> boundaryAnnotationTokens) {
4474  2544 return new LazyTypeVariable(typePool,
4475    typeVariableSource,
4476  2544 annotationTokens == null
4477    ? Collections.<String, List<AnnotationToken>>emptyMap()
4478    : annotationTokens,
4479  2544 boundaryAnnotationTokens == null
4480    ? Collections.<Integer, Map<String, List<AnnotationToken>>>emptyMap()
4481    : boundaryAnnotationTokens,
4482    symbol,
4483    boundTypeTokens);
4484    }
4485   
 
4486  6 toggle @Override
4487    public boolean equals(Object other) {
4488  6 return this == other || !(other == null || getClass() != other.getClass())
4489    && symbol.equals(((Formal) other).symbol)
4490    && boundTypeTokens.equals(((Formal) other).boundTypeTokens);
4491    }
4492   
 
4493  4 toggle @Override
4494    public int hashCode() {
4495  4 return symbol.hashCode() + 31 * boundTypeTokens.hashCode();
4496    }
4497   
 
4498  4 toggle @Override
4499    public String toString() {
4500  4 return "TypePool.Default.LazyTypeDescription.GenericTypeToken.ForTypeVariable.Formal{" +
4501    "symbol='" + symbol + '\'' +
4502    "boundTypeTokens='" + boundTypeTokens + '\'' +
4503    '}';
4504    }
4505   
4506    /**
4507    * A type description that represents a type variable with bounds that are resolved lazily.
4508    */
 
4509    protected static class LazyTypeVariable extends Generic.OfTypeVariable {
4510   
4511    /**
4512    * The type pool to use for locating type descriptions.
4513    */
4514    private final TypePool typePool;
4515   
4516    /**
4517    * The type variable source to use for locating type variables.
4518    */
4519    private final TypeVariableSource typeVariableSource;
4520   
4521    /**
4522    * The type variable's type annotation tokens.
4523    */
4524    private final Map<String, List<AnnotationToken>> annotationTokens;
4525   
4526    /**
4527    * A mapping of the type variable bounds' type annotation tokens by their indices.
4528    */
4529    private final Map<Integer, Map<String, List<AnnotationToken>>> boundaryAnnotationTokens;
4530   
4531    /**
4532    * The type variable's symbol.
4533    */
4534    private final String symbol;
4535   
4536    /**
4537    * Tokenized representations of the type variables bound types.
4538    */
4539    private final List<GenericTypeToken> boundTypeTokens;
4540   
4541    /**
4542    * Creates a lazy type description of a type variables.
4543    *
4544    * @param typePool The type pool to use for locating type descriptions.
4545    * @param typeVariableSource The type variable source to use for locating type variables.
4546    * @param annotationTokens The type variable's type annotation tokens.
4547    * @param boundaryAnnotationTokens A mapping of the type variable bounds' type annotation tokens by their indices.
4548    * @param symbol The type variable's symbol.
4549    * @param boundTypeTokens Tokenized representations of the type variables bound types.
4550    */
 
4551  2544 toggle protected LazyTypeVariable(TypePool typePool,
4552    TypeVariableSource typeVariableSource,
4553    Map<String, List<AnnotationToken>> annotationTokens,
4554    Map<Integer, Map<String, List<AnnotationToken>>> boundaryAnnotationTokens,
4555    String symbol,
4556    List<GenericTypeToken> boundTypeTokens) {
4557  2544 this.typePool = typePool;
4558  2544 this.typeVariableSource = typeVariableSource;
4559  2544 this.annotationTokens = annotationTokens;
4560  2544 this.boundaryAnnotationTokens = boundaryAnnotationTokens;
4561  2544 this.symbol = symbol;
4562  2544 this.boundTypeTokens = boundTypeTokens;
4563    }
4564   
 
4565  346 toggle @Override
4566    public TypeList.Generic getUpperBounds() {
4567  346 return new LazyBoundTokenList(typePool, typeVariableSource, boundaryAnnotationTokens, boundTypeTokens);
4568    }
4569   
 
4570  741 toggle @Override
4571    public TypeVariableSource getVariableSource() {
4572  741 return typeVariableSource;
4573    }
4574   
 
4575  2206 toggle @Override
4576    public String getSymbol() {
4577  2206 return symbol;
4578    }
4579   
 
4580  38 toggle @Override
4581    public AnnotationList getDeclaredAnnotations() {
4582  38 return LazyAnnotationDescription.asListOfNullable(typePool, annotationTokens.get(EMPTY_TYPE_PATH));
4583    }
4584   
4585    /**
4586    * A list representing a formal type variable's bounds.
4587    */
 
4588    protected static class LazyBoundTokenList extends TypeList.Generic.AbstractBase {
4589   
4590    /**
4591    * The type pool to use.
4592    */
4593    private final TypePool typePool;
4594   
4595    /**
4596    * The type variable source for locating type variables.
4597    */
4598    private final TypeVariableSource typeVariableSource;
4599   
4600    /**
4601    * A mapping of the bound type's type annotations by their bound index.
4602    */
4603    private final Map<Integer, Map<String, List<AnnotationToken>>> annotationTokens;
4604   
4605    /**
4606    * The bound types in their tokenized form.
4607    */
4608    private final List<GenericTypeToken> boundTypeTokens;
4609   
4610    /**
4611    * Creates a new lazy bound token list for a type variable.
4612    *
4613    * @param typePool The type pool to use.
4614    * @param typeVariableSource The type variable source for locating type variables.
4615    * @param annotationTokens A mapping of the bound type's type annotations by their bound index.
4616    * @param boundTypeTokens The bound types in their tokenized form.
4617    */
 
4618  346 toggle protected LazyBoundTokenList(TypePool typePool,
4619    TypeVariableSource typeVariableSource,
4620    Map<Integer, Map<String, List<AnnotationToken>>> annotationTokens,
4621    List<GenericTypeToken> boundTypeTokens) {
4622  346 this.typePool = typePool;
4623  346 this.typeVariableSource = typeVariableSource;
4624  346 this.annotationTokens = annotationTokens;
4625  346 this.boundTypeTokens = boundTypeTokens;
4626    }
4627   
 
4628  310 toggle @Override
4629    public Generic get(int index) {
4630  310 Map<String, List<AnnotationToken>> annotationTokens = this.annotationTokens.get(index + (boundTypeTokens.get(0).isPrimaryBound(typePool)
4631    ? 0
4632    : 1));
4633  310 return boundTypeTokens.get(index).toGenericType(typePool,
4634    typeVariableSource,
4635    EMPTY_TYPE_PATH,
4636  310 annotationTokens == null
4637    ? Collections.<String, List<AnnotationToken>>emptyMap()
4638    : annotationTokens);
4639    }
4640   
 
4641  264 toggle @Override
4642    public int size() {
4643  264 return boundTypeTokens.size();
4644    }
4645    }
4646    }
4647    }
4648    }
4649   
4650    /**
4651    * A generic type token that represents a generic array.
4652    */
 
4653    class ForGenericArray implements GenericTypeToken {
4654   
4655    /**
4656    * The array's component type.
4657    */
4658    private final GenericTypeToken componentTypeToken;
4659   
4660    /**
4661    * Creates a generic type token that represents a generic array.
4662    *
4663    * @param componentTypeToken The array's component type.
4664    */
 
4665  2863 toggle public ForGenericArray(GenericTypeToken componentTypeToken) {
4666  2863 this.componentTypeToken = componentTypeToken;
4667    }
4668   
 
4669  288 toggle @Override
4670    public Generic toGenericType(TypePool typePool, TypeVariableSource typeVariableSource, String typePath, Map<String, List<AnnotationToken>> annotationTokens) {
4671  288 return new LazyGenericArray(typePool, typeVariableSource, typePath, annotationTokens, componentTypeToken);
4672    }
4673   
 
4674  1 toggle @Override
4675    public boolean isPrimaryBound(TypePool typePool) {
4676  1 throw new IllegalStateException("A generic array type cannot be a type variable bound: " + this);
4677    }
4678   
 
4679  1 toggle @Override
4680    public String getTypePathPrefix() {
4681  1 throw new IllegalStateException("A generic array type cannot be the owner of a nested type: " + this);
4682    }
4683   
 
4684  5 toggle @Override
4685    public boolean equals(Object other) {
4686  5 return this == other || !(other == null || getClass() != other.getClass())
4687    && componentTypeToken.equals(((ForGenericArray) other).componentTypeToken);
4688    }
4689   
 
4690  3 toggle @Override
4691    public int hashCode() {
4692  3 return componentTypeToken.hashCode();
4693    }
4694   
 
4695  5 toggle @Override
4696    public String toString() {
4697  5 return "TypePool.Default.LazyTypeDescription.GenericTypeToken.ForGenericArray{" +
4698    "componentTypeToken='" + componentTypeToken + '\'' +
4699    '}';
4700    }
4701   
4702    /**
4703    * A generic type representation of a generic array.
4704    */
 
4705    protected static class LazyGenericArray extends Generic.OfGenericArray {
4706   
4707    /**
4708    * The type pool to use.
4709    */
4710    private final TypePool typePool;
4711   
4712    /**
4713    * The type variable source for locating type variables.
4714    */
4715    private final TypeVariableSource typeVariableSource;
4716   
4717    /**
4718    * This type's type path.
4719    */
4720    private final String typePath;
4721   
4722    /**
4723    * This type's type annotations.
4724    */
4725    private final Map<String, List<AnnotationToken>> annotationTokens;
4726   
4727    /**
4728    * A tokenized representation of this generic arrays's component type.
4729    */
4730    private final GenericTypeToken componentTypeToken;
4731   
4732    /**
4733    * Creates a new lazy generic array.
4734    *
4735    * @param typePool The type pool to use.
4736    * @param typeVariableSource The type variable source for locating type variables.
4737    * @param typePath This type's type path.
4738    * @param annotationTokens This type's type annotations.
4739    * @param componentTypeToken A tokenized representation of this generic arrays's component type.
4740    */
 
4741  288 toggle protected LazyGenericArray(TypePool typePool,
4742    TypeVariableSource typeVariableSource,
4743    String typePath,
4744    Map<String, List<AnnotationToken>> annotationTokens,
4745    GenericTypeToken componentTypeToken) {
4746  288 this.typePool = typePool;
4747  288 this.typeVariableSource = typeVariableSource;
4748  288 this.typePath = typePath;
4749  288 this.annotationTokens = annotationTokens;
4750  288 this.componentTypeToken = componentTypeToken;
4751    }
4752   
 
4753  280 toggle @Override
4754    public Generic getComponentType() {
4755  280 return componentTypeToken.toGenericType(typePool, typeVariableSource, typePath + COMPONENT_TYPE_PATH, annotationTokens);
4756    }
4757   
 
4758  48 toggle @Override
4759    public AnnotationList getDeclaredAnnotations() {
4760  48 return LazyAnnotationDescription.asListOfNullable(typePool, annotationTokens.get(typePath));
4761    }
4762    }
4763    }
4764   
4765    /**
4766    * A generic type token for a wildcard that is bound below.
4767    */
 
4768    class ForLowerBoundWildcard implements GenericTypeToken {
4769   
4770    /**
4771    * A token that represents the wildcard's lower bound.
4772    */
4773    private final GenericTypeToken boundTypeToken;
4774   
4775    /**
4776    * Creates a generic type token for a wildcard that is bound below.
4777    *
4778    * @param boundTypeToken A token that represents the wildcard's lower bound.
4779    */
 
4780  1140 toggle public ForLowerBoundWildcard(GenericTypeToken boundTypeToken) {
4781  1140 this.boundTypeToken = boundTypeToken;
4782    }
4783   
 
4784  170 toggle @Override
4785    public Generic toGenericType(TypePool typePool, TypeVariableSource typeVariableSource, String typePath, Map<String, List<AnnotationToken>> annotationTokens) {
4786  170 return new LazyLowerBoundWildcard(typePool, typeVariableSource, typePath, annotationTokens, boundTypeToken);
4787    }
4788   
 
4789  1 toggle @Override
4790    public boolean isPrimaryBound(TypePool typePool) {
4791  1 throw new IllegalStateException("A wildcard type cannot be a type variable bound: " + this);
4792    }
4793   
 
4794  1 toggle @Override
4795    public String getTypePathPrefix() {
4796  1 throw new IllegalStateException("A lower bound wildcard cannot be the owner of a nested type: " + this);
4797    }
4798   
 
4799  5 toggle @Override
4800    public boolean equals(Object other) {
4801  5 return this == other || !(other == null || getClass() != other.getClass())
4802    && boundTypeToken.equals(((ForLowerBoundWildcard) other).boundTypeToken);
4803    }
4804   
 
4805  3 toggle @Override
4806    public int hashCode() {
4807  3 return boundTypeToken.hashCode();
4808    }
4809   
 
4810  5 toggle @Override
4811    public String toString() {
4812  5 return "TypePool.Default.LazyTypeDescription.GenericTypeToken.ForLowerBoundWildcard{" +
4813    "boundTypeToken=" + boundTypeToken +
4814    '}';
4815    }
4816   
4817    /**
4818    * A generic type representation of a lower bound wildcard.
4819    */
 
4820    protected static class LazyLowerBoundWildcard extends Generic.OfWildcardType {
4821   
4822    /**
4823    * The type pool to use.
4824    */
4825    private final TypePool typePool;
4826   
4827    /**
4828    * The type variable source for locating type variables.
4829    */
4830    private final TypeVariableSource typeVariableSource;
4831   
4832    /**
4833    * This type's type path.
4834    */
4835    private final String typePath;
4836   
4837    /**
4838    * This type's type annotations.
4839    */
4840    private final Map<String, List<AnnotationToken>> annotationTokens;
4841   
4842    /**
4843    * A tokenized representation of this wildcard's bound.
4844    */
4845    private final GenericTypeToken boundTypeToken;
4846   
4847    /**
4848    * Creates a new lazy lower bound wildcard.
4849    *
4850    * @param typePool The type pool to use.
4851    * @param typeVariableSource The type variable source for locating type variables.
4852    * @param typePath This type's type path.
4853    * @param annotationTokens This type's type annotations.
4854    * @param boundTypeToken A tokenized representation of this wildcard's bound.
4855    */
 
4856  170 toggle protected LazyLowerBoundWildcard(TypePool typePool,
4857    TypeVariableSource typeVariableSource,
4858    String typePath,
4859    Map<String, List<AnnotationToken>> annotationTokens,
4860    GenericTypeToken boundTypeToken) {
4861  170 this.typePool = typePool;
4862  170 this.typeVariableSource = typeVariableSource;
4863  170 this.typePath = typePath;
4864  170 this.annotationTokens = annotationTokens;
4865  170 this.boundTypeToken = boundTypeToken;
4866    }
4867   
 
4868  8 toggle @Override
4869    public TypeList.Generic getUpperBounds() {
4870  8 return new TypeList.Generic.Explicit(Generic.OBJECT);
4871    }
4872   
 
4873  156 toggle @Override
4874    public TypeList.Generic getLowerBounds() {
4875  156 return new LazyTokenList.ForWildcardBound(typePool, typeVariableSource, typePath, annotationTokens, boundTypeToken);
4876    }
4877   
 
4878  6 toggle @Override
4879    public AnnotationList getDeclaredAnnotations() {
4880  6 return LazyAnnotationDescription.asListOfNullable(typePool, annotationTokens.get(typePath));
4881    }
4882    }
4883    }
4884   
4885    /**
4886    * A generic type token for a wildcard that is bound above.
4887    */
 
4888    class ForUpperBoundWildcard implements GenericTypeToken {
4889   
4890    /**
4891    * A token that represents the wildcard's upper bound.
4892    */
4893    private final GenericTypeToken boundTypeToken;
4894   
4895    /**
4896    * Creates a generic type token for a wildcard that is bound above.
4897    *
4898    * @param boundTypeToken A token that represents the wildcard's upper bound.
4899    */
 
4900  1837 toggle public ForUpperBoundWildcard(GenericTypeToken boundTypeToken) {
4901  1837 this.boundTypeToken = boundTypeToken;
4902    }
4903   
 
4904  108 toggle @Override
4905    public Generic toGenericType(TypePool typePool,
4906    TypeVariableSource typeVariableSource,
4907    String typePath,
4908    Map<String, List<AnnotationToken>> annotationTokens) {
4909  108 return new LazyUpperBoundWildcard(typePool, typeVariableSource, typePath, annotationTokens, boundTypeToken);
4910    }
4911   
 
4912  1 toggle @Override
4913    public boolean isPrimaryBound(TypePool typePool) {
4914  1 throw new IllegalStateException("A wildcard type cannot be a type variable bound: " + this);
4915    }
4916   
 
4917  1 toggle @Override
4918    public String getTypePathPrefix() {
4919  1 throw new IllegalStateException("An upper bound wildcard cannot be the owner of a nested type: " + this);
4920    }
4921   
 
4922  5 toggle @Override
4923    public boolean equals(Object other) {
4924  5 return this == other || !(other == null || getClass() != other.getClass())
4925    && boundTypeToken.equals(((ForUpperBoundWildcard) other).boundTypeToken);
4926    }
4927   
 
4928  3 toggle @Override
4929    public int hashCode() {
4930  3 return boundTypeToken.hashCode();
4931    }
4932   
 
4933  5 toggle @Override
4934    public String toString() {
4935  5 return "TypePool.Default.LazyTypeDescription.GenericTypeToken.ForUpperBoundWildcard{" +
4936    "boundTypeToken=" + boundTypeToken +
4937    '}';
4938    }
4939   
4940    /**
4941    * A generic type representation of a tokenized wildcard with an upper bound.
4942    */
 
4943    protected static class LazyUpperBoundWildcard extends Generic.OfWildcardType {
4944   
4945    /**
4946    * The type pool to use.
4947    */
4948    private final TypePool typePool;
4949   
4950    /**
4951    * The type variable source for locating type variables.
4952    */
4953    private final TypeVariableSource typeVariableSource;
4954   
4955    /**
4956    * This type's type path.
4957    */
4958    private final String typePath;
4959   
4960    /**
4961    * This type's type annotations.
4962    */
4963    private final Map<String, List<AnnotationToken>> annotationTokens;
4964   
4965    /**
4966    * A tokenized representation of this wildcard's bound.
4967    */
4968    private final GenericTypeToken boundTypeToken;
4969   
4970    /**
4971    * Creates a new lazy upper bound wildcard.
4972    *
4973    * @param typePool The type pool to use.
4974    * @param typeVariableSource The type variable source for locating type variables.
4975    * @param typePath This type's type path.
4976    * @param annotationTokens This type's type annotations.
4977    * @param boundTypeToken A tokenized representation of this wildcard's bound.
4978    */
 
4979  108 toggle protected LazyUpperBoundWildcard(TypePool typePool,
4980    TypeVariableSource typeVariableSource,
4981    String typePath,
4982    Map<String, List<AnnotationToken>> annotationTokens,
4983    GenericTypeToken boundTypeToken) {
4984  108 this.typePool = typePool;
4985  108 this.typeVariableSource = typeVariableSource;
4986  108 this.typePath = typePath;
4987  108 this.annotationTokens = annotationTokens;
4988  108 this.boundTypeToken = boundTypeToken;
4989    }
4990   
 
4991  92 toggle @Override
4992    public TypeList.Generic getUpperBounds() {
4993  92 return new LazyTokenList.ForWildcardBound(typePool, typeVariableSource, typePath, annotationTokens, boundTypeToken);
4994    }
4995   
 
4996  76 toggle @Override
4997    public TypeList.Generic getLowerBounds() {
4998  76 return new TypeList.Generic.Empty();
4999    }
5000   
 
5001  6 toggle @Override
5002    public AnnotationList getDeclaredAnnotations() {
5003  6 return LazyAnnotationDescription.asListOfNullable(typePool, annotationTokens.get(typePath));
5004    }
5005    }
5006    }
5007   
5008    /**
5009    * A generic type token that represents a parameterized type.
5010    */
 
5011    class ForParameterizedType implements GenericTypeToken {
5012   
5013    /**
5014    * The name of the parameterized type's erasure.
5015    */
5016    private final String name;
5017   
5018    /**
5019    * A list of tokens that represent the parameters of the represented type.
5020    */
5021    private final List<GenericTypeToken> parameterTypeTokens;
5022   
5023    /**
5024    * Creates a type token that represents a parameterized type.
5025    *
5026    * @param name The name of the parameterized type's erasure.
5027    * @param parameterTypeTokens A list of tokens that represent the parameters of the represented type.
5028    */
 
5029  13431 toggle public ForParameterizedType(String name, List<GenericTypeToken> parameterTypeTokens) {
5030  13431 this.name = name;
5031  13431 this.parameterTypeTokens = parameterTypeTokens;
5032    }
5033   
 
5034  1171 toggle @Override
5035    public Generic toGenericType(TypePool typePool, TypeVariableSource typeVariableSource, String typePath, Map<String, List<AnnotationToken>> annotationTokens) {
5036  1171 return new LazyParameterizedType(typePool, typeVariableSource, typePath, annotationTokens, name, parameterTypeTokens);
5037    }
5038   
 
5039  74 toggle @Override
5040    public boolean isPrimaryBound(TypePool typePool) {
5041  74 return !typePool.describe(name).resolve().isInterface();
5042    }
5043   
 
5044  60 toggle @Override
5045    public String getTypePathPrefix() {
5046  60 return String.valueOf(INNER_CLASS_PATH);
5047    }
5048   
 
5049  6 toggle @Override
5050    public boolean equals(Object other) {
5051  6 return this == other || !(other == null || getClass() != other.getClass())
5052    && name.equals(((ForParameterizedType) other).name)
5053    && parameterTypeTokens.equals(((ForParameterizedType) other).parameterTypeTokens);
5054    }
5055   
 
5056  4 toggle @Override
5057    public int hashCode() {
5058  4 return name.hashCode() + 31 * parameterTypeTokens.hashCode();
5059    }
5060   
 
5061  4 toggle @Override
5062    public String toString() {
5063  4 return "TypePool.Default.LazyTypeDescription.GenericTypeToken.ForParameterizedType{" +
5064    "name='" + name + '\'' +
5065    ", parameterTypeTokens=" + parameterTypeTokens +
5066    '}';
5067    }
5068   
5069    /**
5070    * A generic type token to describe a parameterized type description with a generic owner type.
5071    */
 
5072    public static class Nested implements GenericTypeToken {
5073   
5074    /**
5075    * The name of the parameterized type's erasure.
5076    */
5077    private final String name;
5078   
5079    /**
5080    * A list of tokens that represent the parameters of the represented type.
5081    */
5082    private final List<GenericTypeToken> parameterTypeTokens;
5083   
5084    /**
5085    * A token that describes the described parameterized type's owner type.
5086    */
5087    private final GenericTypeToken ownerTypeToken;
5088   
5089    /**
5090    * Creates a type token that represents a parameterized type.
5091    *
5092    * @param name The name of the parameterized type's erasure.
5093    * @param parameterTypeTokens A list of tokens that represent the parameters of the represented type.
5094    * @param ownerTypeToken A token that describes the described parameterized type's owner type.
5095    */
 
5096  455 toggle public Nested(String name, List<GenericTypeToken> parameterTypeTokens, GenericTypeToken ownerTypeToken) {
5097  455 this.name = name;
5098  455 this.parameterTypeTokens = parameterTypeTokens;
5099  455 this.ownerTypeToken = ownerTypeToken;
5100    }
5101   
 
5102  98 toggle @Override
5103    public Generic toGenericType(TypePool typePool,
5104    TypeVariableSource typeVariableSource,
5105    String typePath,
5106    Map<String, List<AnnotationToken>> annotationTokens) {
5107  98 return new LazyParameterizedType(typePool, typeVariableSource, typePath, annotationTokens, name, parameterTypeTokens, ownerTypeToken);
5108    }
5109   
 
5110  0 toggle @Override
5111    public String getTypePathPrefix() {
5112  0 return ownerTypeToken.getTypePathPrefix() + INNER_CLASS_PATH;
5113    }
5114   
 
5115  0 toggle @Override
5116    public boolean isPrimaryBound(TypePool typePool) {
5117  0 return !typePool.describe(name).resolve().isInterface();
5118    }
5119   
 
5120  7 toggle @Override
5121    public boolean equals(Object other) {
5122  1 if (this == other) return true;
5123  2 if (other == null || getClass() != other.getClass()) return false;
5124  4 Nested nested = (Nested) other;
5125  4 return name.equals(nested.name)
5126    && parameterTypeTokens.equals(nested.parameterTypeTokens)
5127    && ownerTypeToken.equals(nested.ownerTypeToken);
5128    }
5129   
 
5130  5 toggle @Override
5131    public int hashCode() {
5132  5 int result = name.hashCode();
5133  5 result = 31 * result + parameterTypeTokens.hashCode();
5134  5 result = 31 * result + ownerTypeToken.hashCode();
5135  5 return result;
5136    }
5137   
 
5138  5 toggle @Override
5139    public String toString() {
5140  5 return "TypePool.Default.LazyTypeDescription.GenericTypeToken.ForParameterizedType.Nested{" +
5141    "name='" + name + '\'' +
5142    ", parameterTypeTokens=" + parameterTypeTokens +
5143    ", ownerTypeToken=" + ownerTypeToken +
5144    '}';
5145    }
5146   
5147    /**
5148    * A lazy description of a parameterized type with an owner type.
5149    */
 
5150    protected static class LazyParameterizedType extends Generic.OfParameterizedType {
5151   
5152    /**
5153    * The type pool that is used for locating a generic type.
5154    */
5155    private final TypePool typePool;
5156   
5157    /**
5158    * The type variable source to use for resolving type variables.
5159    */
5160    private final TypeVariableSource typeVariableSource;
5161   
5162    /**
5163    * This type's type path.
5164    */
5165    private final String typePath;
5166   
5167    /**
5168    * A mapping of type annotations for this type.
5169    */
5170    private final Map<String, List<AnnotationToken>> annotationTokens;
5171   
5172    /**
5173    * The binary name of this parameterized type's raw type.
5174    */
5175    private final String name;
5176   
5177    /**
5178    * Tokens that represent this parameterized type's parameters.
5179    */
5180    private final List<GenericTypeToken> parameterTypeTokens;
5181   
5182    /**
5183    * A token that represents this type's owner type.
5184    */
5185    private final GenericTypeToken ownerTypeToken;
5186   
5187    /**
5188    * Creates a new lazy parameterized type.
5189    *
5190    * @param typePool The type pool that is used for locating a generic type.
5191    * @param typeVariableSource The type variable source to use for resolving type variables.
5192    * @param typePath This type's type path.
5193    * @param annotationTokens A mapping of type annotations for this type.
5194    * @param name The binary name of this parameterized type's raw type.
5195    * @param parameterTypeTokens Tokens that represent this parameterized type's parameters.
5196    * @param ownerTypeToken A token that represents this type's owner type.
5197    */
 
5198  98 toggle protected LazyParameterizedType(TypePool typePool,
5199    TypeVariableSource typeVariableSource,
5200    String typePath,
5201    Map<String, List<AnnotationToken>> annotationTokens,
5202    String name,
5203    List<GenericTypeToken> parameterTypeTokens,
5204    GenericTypeToken ownerTypeToken) {
5205  98 this.typePool = typePool;
5206  98 this.typeVariableSource = typeVariableSource;
5207  98 this.typePath = typePath;
5208  98 this.annotationTokens = annotationTokens;
5209  98 this.name = name;
5210  98 this.parameterTypeTokens = parameterTypeTokens;
5211  98 this.ownerTypeToken = ownerTypeToken;
5212    }
5213   
 
5214  48 toggle @Override
5215    public TypeDescription asErasure() {
5216  48 return typePool.describe(name).resolve();
5217    }
5218   
 
5219  54 toggle @Override
5220    public TypeList.Generic getTypeArguments() {
5221  54 return new LazyTokenList(typePool, typeVariableSource, typePath + ownerTypeToken.getTypePathPrefix(), annotationTokens, parameterTypeTokens);
5222    }
5223   
 
5224  42 toggle @Override
5225    public Generic getOwnerType() {
5226  42 return ownerTypeToken.toGenericType(typePool, typeVariableSource, typePath, annotationTokens);
5227    }
5228   
 
5229  6 toggle @Override
5230    public AnnotationList getDeclaredAnnotations() {
5231  6 return LazyAnnotationDescription.asListOfNullable(typePool, annotationTokens.get(typePath + ownerTypeToken.getTypePathPrefix()));
5232    }
5233    }
5234    }
5235   
5236    /**
5237    * A generic type description that represents a parameterized type <b>without</b> an enclosing generic owner type.
5238    */
 
5239    protected static class LazyParameterizedType extends Generic.OfParameterizedType {
5240   
5241    /**
5242    * The type pool that is used for locating a generic type.
5243    */
5244    private final TypePool typePool;
5245   
5246    /**
5247    * The type variable source to use for resolving type variables.
5248    */
5249    private final TypeVariableSource typeVariableSource;
5250   
5251    /**
5252    * This type's type path.
5253    */
5254    private final String typePath;
5255   
5256    /**
5257    * A mapping of the represent type's annotation tokens.
5258    */
5259    private final Map<String, List<AnnotationToken>> annotationTokens;
5260   
5261    /**
5262    * The binary name of the raw type.
5263    */
5264    private final String name;
5265   
5266    /**
5267    * A list of type tokens representing this type's bounds.
5268    */
5269    private final List<GenericTypeToken> parameterTypeTokens;
5270   
5271    /**
5272    * Creates a new description of a parameterized type.
5273    *
5274    * @param typePool The type pool that is used for locating a generic type.
5275    * @param typeVariableSource The type variable source to use for resolving type variables.
5276    * @param typePath This type's type path.
5277    * @param annotationTokens A mapping of the represent type's annotation tokens,
5278    * @param name The binary name of the raw type.
5279    * @param parameterTypeTokens A list of type tokens representing this type's bounds.
5280    */
 
5281  1171 toggle protected LazyParameterizedType(TypePool typePool,
5282    TypeVariableSource typeVariableSource,
5283    String typePath,
5284    Map<String, List<AnnotationToken>> annotationTokens,
5285    String name,
5286    List<GenericTypeToken> parameterTypeTokens) {
5287  1171 this.typePool = typePool;
5288  1171 this.typeVariableSource = typeVariableSource;
5289  1171 this.typePath = typePath;
5290  1171 this.annotationTokens = annotationTokens;
5291  1171 this.name = name;
5292  1171 this.parameterTypeTokens = parameterTypeTokens;
5293    }
5294   
 
5295  626 toggle @Override
5296    public TypeDescription asErasure() {
5297  626 return typePool.describe(name).resolve();
5298    }
5299   
 
5300  933 toggle @Override
5301    public TypeList.Generic getTypeArguments() {
5302  933 return new LazyTokenList(typePool, typeVariableSource, typePath, annotationTokens, parameterTypeTokens);
5303    }
5304   
 
5305  341 toggle @Override
5306    public Generic getOwnerType() {
5307  341 TypeDescription ownerType = typePool.describe(name).resolve().getEnclosingType();
5308  341 return ownerType == null
5309    ? UNDEFINED
5310    : ownerType.asGenericType();
5311    }
5312   
 
5313  112 toggle @Override
5314    public AnnotationList getDeclaredAnnotations() {
5315  112 return LazyAnnotationDescription.asListOfNullable(typePool, annotationTokens.get(typePath));
5316    }
5317    }
5318    }
5319   
5320    /**
5321    * A lazy list of type tokens.
5322    */
 
5323    class LazyTokenList extends TypeList.Generic.AbstractBase {
5324   
5325    /**
5326    * The type pool that is used for locating a generic type.
5327    */
5328    private final TypePool typePool;
5329   
5330    /**
5331    * The type variable source to use for resolving type variables.
5332    */
5333    private final TypeVariableSource typeVariableSource;
5334   
5335    /**
5336    * The represented types' type path to which an index step is added upon resolution.
5337    */
5338    private final String typePath;
5339   
5340    /**
5341    * A mapping of the represent types' annotation tokens.
5342    */
5343    private final Map<String, List<AnnotationToken>> annotationTokens;
5344   
5345    /**
5346    * A list of type tokens this list represents.
5347    */
5348    private final List<GenericTypeToken> genericTypeTokens;
5349   
5350    /**
5351    * Creates a new type list that represents a list of tokenized types.
5352    *
5353    * @param typePool The type pool that is used for locating a generic type.
5354    * @param typeVariableSource The type variable source to use for resolving type variables.
5355    * @param typePath The represented types' type path to which an index step is added upon resolution.
5356    * @param annotationTokens A mapping of the represent types' annotation tokens,
5357    * @param genericTypeTokens A list of type tokens this list represents.
5358    */
 
5359  987 toggle protected LazyTokenList(TypePool typePool,
5360    TypeVariableSource typeVariableSource,
5361    String typePath,
5362    Map<String, List<AnnotationToken>> annotationTokens,
5363    List<GenericTypeToken> genericTypeTokens) {
5364  987 this.typePool = typePool;
5365  987 this.typeVariableSource = typeVariableSource;
5366  987 this.typePath = typePath;
5367  987 this.annotationTokens = annotationTokens;
5368  987 this.genericTypeTokens = genericTypeTokens;
5369    }
5370   
 
5371  985 toggle @Override
5372    public Generic get(int index) {
5373  985 return genericTypeTokens.get(index).toGenericType(typePool, typeVariableSource, typePath + index + INDEXED_TYPE_DELIMITER, annotationTokens);
5374    }
5375   
 
5376  1586 toggle @Override
5377    public int size() {
5378  1586 return genericTypeTokens.size();
5379    }
5380   
5381    /**
5382    * A generic type description representing a tokenized wildcard bound.
5383    */
 
5384    protected static class ForWildcardBound extends TypeList.Generic.AbstractBase {
5385   
5386    /**
5387    * The type pool that is used for locating a generic type.
5388    */
5389    private final TypePool typePool;
5390   
5391    /**
5392    * The type variable source to use for resolving type variables.
5393    */
5394    private final TypeVariableSource typeVariableSource;
5395   
5396    /**
5397    * The represented types' type path to which a wildcard step is added upon resolution.
5398    */
5399    private final String typePath;
5400   
5401    /**
5402    * A mapping of the represent types' annotation tokens.
5403    */
5404    private final Map<String, List<AnnotationToken>> annotationTokens;
5405   
5406    /**
5407    * A token representing the wildcard's bound.
5408    */
5409    private final GenericTypeToken genericTypeToken;
5410   
5411    /**
5412    * @param typePool The type pool that is used for locating a generic type.
5413    * @param typeVariableSource The type variable source to use for resolving type variables.
5414    * @param typePath The represented types' type path to which a wildcard step is added upon resolution.
5415    * @param annotationTokens A mapping of the represent types' annotation tokens,
5416    * @param genericTypeToken A token representing the wildcard's bound.
5417    */
 
5418  248 toggle protected ForWildcardBound(TypePool typePool,
5419    TypeVariableSource typeVariableSource,
5420    String typePath,
5421    Map<String, List<AnnotationToken>> annotationTokens,
5422    GenericTypeToken genericTypeToken) {
5423  248 this.typePool = typePool;
5424  248 this.typeVariableSource = typeVariableSource;
5425  248 this.typePath = typePath;
5426  248 this.annotationTokens = annotationTokens;
5427  248 this.genericTypeToken = genericTypeToken;
5428    }
5429   
 
5430  272 toggle @Override
5431    public Generic get(int index) {
5432  272 if (index == 0) {
5433  272 return genericTypeToken.toGenericType(typePool, typeVariableSource, typePath + WILDCARD_TYPE_PATH, annotationTokens);
5434    } else {
5435  0 throw new IndexOutOfBoundsException("index = " + index);
5436    }
5437    }
5438   
 
5439  428 toggle @Override
5440    public int size() {
5441  428 return 1;
5442    }
5443    }
5444    }
5445    }
5446   
5447    /**
5448    * A token for representing collected data on an annotation.
5449    */
 
5450    protected static class AnnotationToken {
5451   
5452    /**
5453    * The descriptor of the represented annotation.
5454    */
5455    private final String descriptor;
5456   
5457    /**
5458    * A map of annotation value names to their value representations.
5459    */
5460    private final Map<String, AnnotationDescription.AnnotationValue<?, ?>> values;
5461   
5462    /**
5463    * Creates a new annotation token.
5464    *
5465    * @param descriptor The descriptor of the represented annotation.
5466    * @param values A map of annotation value names to their value representations.
5467    */
 
5468  23060 toggle protected AnnotationToken(String descriptor, Map<String, AnnotationDescription.AnnotationValue<?, ?>> values) {
5469  23060 this.descriptor = descriptor;
5470  23060 this.values = values;
5471    }
5472   
5473    /**
5474    * Returns a map of annotation value names to their value representations.
5475    *
5476    * @return A map of annotation value names to their value representations.
5477    */
 
5478  178 toggle protected Map<String, AnnotationDescription.AnnotationValue<?, ?>> getValues() {
5479  178 return values;
5480    }
5481   
5482    /**
5483    * Returns the annotation type's binary name.
5484    *
5485    * @return The annotation type's binary name.
5486    */
 
5487  1383 toggle protected String getBinaryName() {
5488  1383 return descriptor.substring(1, descriptor.length() - 1).replace('/', '.');
5489    }
5490   
5491    /**
5492    * Transforms this token into an annotation description.
5493    *
5494    * @param typePool The type pool to be used for looking up linked types.
5495    * @return An optional description of this annotation's token.
5496    */
 
5497  1199 toggle private Resolution toAnnotationDescription(TypePool typePool) {
5498  1199 TypePool.Resolution resolution = typePool.describe(getBinaryName());
5499  1199 return resolution.isResolved()
5500    ? new Resolution.Simple(new LazyAnnotationDescription(typePool, resolution.resolve(), values))
5501    : new Resolution.Illegal(getBinaryName());
5502    }
5503   
 
5504  6 toggle @Override
5505    public boolean equals(Object other) {
5506  1 if (this == other) return true;
5507  2 if (other == null || getClass() != other.getClass()) return false;
5508  3 AnnotationToken that = (AnnotationToken) other;
5509  3 return descriptor.equals(that.descriptor)
5510    && values.equals(that.values);
5511    }
5512   
 
5513  4 toggle @Override
5514    public int hashCode() {
5515  4 int result = descriptor.hashCode();
5516  4 result = 31 * result + values.hashCode();
5517  4 return result;
5518    }
5519   
 
5520  4 toggle @Override
5521    public String toString() {
5522  4 return "TypePool.Default.LazyTypeDescription.AnnotationToken{" +
5523    "descriptor='" + descriptor + '\'' +
5524    ", values=" + values +
5525    '}';
5526    }
5527   
5528    /**
5529    * A resolution for an annotation tokens. Any annotation is suppressed if its type is not available.
5530    * This conforms to the handling of the Java reflection API.
5531    */
 
5532    protected interface Resolution {
5533   
5534    /**
5535    * Returns {@code true} if the represented annotation could be resolved.
5536    *
5537    * @return {@code true} if the represented annotation could be resolved.
5538    */
5539    boolean isResolved();
5540   
5541    /**
5542    * Returns the resolved annotation. This method throws an exception if this instance is not resolved.
5543    *
5544    * @return The resolved annotation. This method throws an exception if this instance is not resolved.
5545    */
5546    AnnotationDescription resolve();
5547   
5548    /**
5549    * A simple resolved annotation.
5550    */
 
5551    class Simple implements Resolution {
5552   
5553    /**
5554    * The represented annotation description.
5555    */
5556    private final AnnotationDescription annotationDescription;
5557   
5558    /**
5559    * Creates a new simple resolution.
5560    *
5561    * @param annotationDescription The represented annotation description.
5562    */
 
5563  1196 toggle protected Simple(AnnotationDescription annotationDescription) {
5564  1196 this.annotationDescription = annotationDescription;
5565    }
5566   
 
5567  1147 toggle @Override
5568    public boolean isResolved() {
5569  1147 return true;
5570    }
5571   
 
5572  1193 toggle @Override
5573    public AnnotationDescription resolve() {
5574  1193 return annotationDescription;
5575    }
5576   
 
5577  5 toggle @Override
5578    public boolean equals(Object other) {
5579  5 return this == other || !(other == null || getClass() != other.getClass())
5580    && annotationDescription.equals(((Simple) other).annotationDescription);
5581    }
5582   
 
5583  3 toggle @Override
5584    public int hashCode() {
5585  3 return annotationDescription.hashCode();
5586    }
5587   
 
5588  3 toggle @Override
5589    public String toString() {
5590  3 return "TypePool.Default.LazyTypeDescription.AnnotationToken.Resolution.Simple{" +
5591    "annotationDescription=" + annotationDescription +
5592    '}';
5593    }
5594    }
5595   
5596    /**
5597    * An illegal resolution.
5598    */
 
5599    class Illegal implements Resolution {
5600   
5601    /**
5602    * The annotation's binary type name.
5603    */
5604    private final String annotationType;
5605   
5606    /**
5607    * Creates a new illegal resolution.
5608    *
5609    * @param annotationType The annotation's binary type name.
5610    */
 
5611  11 toggle public Illegal(String annotationType) {
5612  11 this.annotationType = annotationType;
5613    }
5614   
 
5615  7 toggle @Override
5616    public boolean isResolved() {
5617  7 return false;
5618    }
5619   
 
5620  1 toggle @Override
5621    public AnnotationDescription resolve() {
5622  1 throw new IllegalStateException("Annotation type is not available: " + annotationType);
5623    }
5624   
 
5625  5 toggle @Override
5626    public boolean equals(Object other) {
5627  5 return this == other || !(other == null || getClass() != other.getClass())
5628    && annotationType.equals(((Illegal) other).annotationType);
5629    }
5630   
 
5631  3 toggle @Override
5632    public int hashCode() {
5633  3 return annotationType.hashCode();
5634    }
5635   
 
5636  3 toggle @Override
5637    public String toString() {
5638  3 return "TypePool.Default.LazyTypeDescription.AnnotationToken.Resolution.Illegal{" +
5639    "annotationType=" + annotationType +
5640    '}';
5641    }
5642    }
5643    }
5644    }
5645   
5646    /**
5647    * A token for representing collected data on a field.
5648    */
 
5649    protected static class FieldToken {
5650   
5651    /**
5652    * The name of the field.
5653    */
5654    private final String name;
5655   
5656    /**
5657    * The modifiers of the represented field.
5658    */
5659    private final int modifiers;
5660   
5661    /**
5662    * The descriptor of the field.
5663    */
5664    private final String descriptor;
5665   
5666    /**
5667    * The resolution of this field's generic type.
5668    */
5669    private final GenericTypeToken.Resolution.ForField signatureResolution;
5670   
5671    /**
5672    * A mapping of the field type's type annotation tokens.
5673    */
5674    private final Map<String, List<AnnotationToken>> typeAnnotationTokens;
5675   
5676    /**
5677    * A list of annotation tokens representing the annotations of the represented field.
5678    */
5679    private final List<AnnotationToken> annotationTokens;
5680   
5681    /**
5682    * Creates a new field token.
5683    *
5684    * @param name The name of the field.
5685    * @param modifiers The modifiers of the represented field.
5686    * @param descriptor The descriptor of the field.
5687    * @param signatureResolution The resolution of this field's generic type.
5688    * @param typeAnnotationTokens A mapping of the field type's type annotation tokens.
5689    * @param annotationTokens A list of annotation tokens representing the annotations of the represented field.
5690    */
 
5691  8592 toggle protected FieldToken(String name,
5692    int modifiers,
5693    String descriptor,
5694    GenericTypeToken.Resolution.ForField signatureResolution,
5695    Map<String, List<AnnotationToken>> typeAnnotationTokens,
5696    List<AnnotationToken> annotationTokens) {
5697  8592 this.modifiers = modifiers;
5698  8592 this.name = name;
5699  8592 this.descriptor = descriptor;
5700  8592 this.signatureResolution = signatureResolution;
5701  8592 this.typeAnnotationTokens = typeAnnotationTokens;
5702  8592 this.annotationTokens = annotationTokens;
5703    }
5704   
5705    /**
5706    * Transforms this token into a lazy field description.
5707    *
5708    * @param lazyTypeDescription The lazy type description to attach this field description to.
5709    * @return A field description resembling this field token.
5710    */
 
5711  829 toggle private LazyFieldDescription toFieldDescription(LazyTypeDescription lazyTypeDescription) {
5712  829 return lazyTypeDescription.new LazyFieldDescription(name,
5713    modifiers,
5714    descriptor,
5715    signatureResolution,
5716    typeAnnotationTokens,
5717    annotationTokens);
5718    }
5719   
 
5720  10 toggle @Override
5721    public boolean equals(Object other) {
5722  1 if (this == other) return true;
5723  2 if (other == null || getClass() != other.getClass()) return false;
5724  7 FieldToken that = (FieldToken) other;
5725  7 return modifiers == that.modifiers
5726    && annotationTokens.equals(that.annotationTokens)
5727    && descriptor.equals(that.descriptor)
5728    && signatureResolution.equals(that.signatureResolution)
5729    && typeAnnotationTokens.equals(that.typeAnnotationTokens)
5730    && name.equals(that.name);
5731    }
5732   
 
5733  8 toggle @Override
5734    public int hashCode() {
5735  8 int result = modifiers;
5736  8 result = 31 * result + name.hashCode();
5737  8 result = 31 * result + descriptor.hashCode();
5738  8 result = 31 * result + signatureResolution.hashCode();
5739  8 result = 31 * result + typeAnnotationTokens.hashCode();
5740  8 result = 31 * result + annotationTokens.hashCode();
5741  8 return result;
5742    }
5743   
 
5744  8 toggle @Override
5745    public String toString() {
5746  8 return "TypePool.Default.LazyTypeDescription.FieldToken{" +
5747    "modifiers=" + modifiers +
5748    ", name='" + name + '\'' +
5749    ", descriptor='" + descriptor + '\'' +
5750    ", signatureResolution=" + signatureResolution +
5751    ", typeAnnotationTokens=" + typeAnnotationTokens +
5752    ", annotationTokens=" + annotationTokens +
5753    '}';
5754    }
5755    }
5756   
5757    /**
5758    * A token for representing collected data on a method.
5759    */
 
5760    protected static class MethodToken {
5761   
5762    /**
5763    * The internal name of the represented method.
5764    */
5765    private final String name;
5766   
5767    /**
5768    * The modifiers of the represented method.
5769    */
5770    private final int modifiers;
5771   
5772    /**
5773    * The descriptor of the represented method.
5774    */
5775    private final String descriptor;
5776   
5777    /**
5778    * The generic type resolution of this method.
5779    */
5780    private final GenericTypeToken.Resolution.ForMethod signatureResolution;
5781   
5782    /**
5783    * An array of internal names of the exceptions of the represented method or {@code null} if there
5784    * are no such exceptions.
5785    */
5786    private final String[] exceptionName;
5787   
5788    /**
5789    * A mapping of the type variables' type annotation tokens by their indices.
5790    */
5791    private final Map<Integer, Map<String, List<AnnotationToken>>> typeVariableAnnotationTokens;
5792   
5793    /**
5794    * A mapping of the type variables' type bounds' type annotation tokens by their indices and each variable's index.
5795    */
5796    private final Map<Integer, Map<Integer, Map<String, List<AnnotationToken>>>> typeVariableBoundAnnotationTokens;
5797   
5798    /**
5799    * A mapping of the return type's type variable tokens.
5800    */
5801    private final Map<String, List<AnnotationToken>> returnTypeAnnotationTokens;
5802   
5803    /**
5804    * A mapping of the parameter types' type annotation tokens by their indices.
5805    */
5806    private final Map<Integer, Map<String, List<AnnotationToken>>> parameterTypeAnnotationTokens;
5807   
5808    /**
5809    * A mapping of the exception types' type annotation tokens by their indices.
5810    */
5811    private final Map<Integer, Map<String, List<AnnotationToken>>> exceptionTypeAnnotationTokens;
5812   
5813    /**
5814    * A mapping of the receiver type's annotation tokens.
5815    */
5816    private final Map<String, List<AnnotationToken>> receiverTypeAnnotationTokens;
5817   
5818    /**
5819    * A list of annotation tokens that are present on the represented method.
5820    */
5821    private final List<AnnotationToken> annotationTokens;
5822   
5823    /**
5824    * A map of parameter indices to tokens that represent their annotations.
5825    */
5826    private final Map<Integer, List<AnnotationToken>> parameterAnnotationTokens;
5827   
5828    /**
5829    * A list of tokens describing meta data of the method's parameters.
5830    */
5831    private final List<ParameterToken> parameterTokens;
5832   
5833    /**
5834    * The default value of this method or {@code null} if there is no such value.
5835    */
5836    private final AnnotationDescription.AnnotationValue<?, ?> defaultValue;
5837   
5838    /**
5839    * Creates a new method token.
5840    *
5841    * @param name The name of the method.
5842    * @param modifiers The modifiers of the represented method.
5843    * @param descriptor The descriptor of the represented method.
5844    * @param signatureResolution The generic type resolution of this method.
5845    * @param exceptionName An array of internal names of the exceptions of the represented method or {@code null} if
5846    * there are no such exceptions.
5847    * @param typeVariableAnnotationTokens A mapping of the type variables' type annotation tokens by their indices.
5848    * @param typeVariableBoundAnnotationTokens A mapping of the type variables' type bounds' type annotation tokens by their
5849    * index and each variable's index.
5850    * @param returnTypeAnnotationTokens A mapping of the return type's type variable tokens.
5851    * @param parameterTypeAnnotationTokens A mapping of the parameter types' type annotation tokens by their indices.
5852    * @param exceptionTypeAnnotationTokens A mapping of the exception types' type annotation tokens by their indices.
5853    * @param receiverTypeAnnotationTokens A mapping of the receiver type's annotation tokens.
5854    * @param annotationTokens A list of annotation tokens that are present on the represented method.
5855    * @param parameterAnnotationTokens A map of parameter indices to tokens that represent their annotations.
5856    * @param parameterTokens A list of tokens describing meta data of the method's parameters.
5857    * @param defaultValue The default value of this method or {@code null} if there is no such value.
5858    */
 
5859  105222 toggle protected MethodToken(String name,
5860    int modifiers,
5861    String descriptor,
5862    GenericTypeToken.Resolution.ForMethod signatureResolution,
5863    String[] exceptionName,
5864    Map<Integer, Map<String, List<AnnotationToken>>> typeVariableAnnotationTokens,
5865    Map<Integer, Map<Integer, Map<String, List<AnnotationToken>>>> typeVariableBoundAnnotationTokens,
5866    Map<String, List<AnnotationToken>> returnTypeAnnotationTokens,
5867    Map<Integer, Map<String, List<AnnotationToken>>> parameterTypeAnnotationTokens,
5868    Map<Integer, Map<String, List<AnnotationToken>>> exceptionTypeAnnotationTokens,
5869    Map<String, List<AnnotationToken>> receiverTypeAnnotationTokens,
5870    List<AnnotationToken> annotationTokens,
5871    Map<Integer, List<AnnotationToken>> parameterAnnotationTokens,
5872    List<ParameterToken> parameterTokens,
5873    AnnotationDescription.AnnotationValue<?, ?> defaultValue) {
5874  105222 this.modifiers = modifiers;
5875  105222 this.name = name;
5876  105222 this.descriptor = descriptor;
5877  105222 this.signatureResolution = signatureResolution;
5878  105222 this.exceptionName = exceptionName;
5879  105222 this.typeVariableAnnotationTokens = typeVariableAnnotationTokens;
5880  105222 this.typeVariableBoundAnnotationTokens = typeVariableBoundAnnotationTokens;
5881  105222 this.returnTypeAnnotationTokens = returnTypeAnnotationTokens;
5882  105222 this.parameterTypeAnnotationTokens = parameterTypeAnnotationTokens;
5883  105222 this.exceptionTypeAnnotationTokens = exceptionTypeAnnotationTokens;
5884  105222 this.receiverTypeAnnotationTokens = receiverTypeAnnotationTokens;
5885  105222 this.annotationTokens = annotationTokens;
5886  105222 this.parameterAnnotationTokens = parameterAnnotationTokens;
5887  105222 this.parameterTokens = parameterTokens;
5888  105222 this.defaultValue = defaultValue;
5889    }
5890   
5891    /**
5892    * Transforms this method token to a method description that is attached to a lazy type description.
5893    *
5894    * @param lazyTypeDescription The lazy type description to attach this method description to.
5895    * @return A method description representing this field token.
5896    */
 
5897  14863 toggle private MethodDescription.InDefinedShape toMethodDescription(LazyTypeDescription lazyTypeDescription) {
5898  14863 return lazyTypeDescription.new LazyMethodDescription(name,
5899    modifiers,
5900    descriptor,
5901    signatureResolution,
5902    exceptionName,
5903    typeVariableAnnotationTokens,
5904    typeVariableBoundAnnotationTokens,
5905    returnTypeAnnotationTokens,
5906    parameterTypeAnnotationTokens,
5907    exceptionTypeAnnotationTokens,
5908    receiverTypeAnnotationTokens,
5909    annotationTokens,
5910    parameterAnnotationTokens,
5911    parameterTokens,
5912    defaultValue);
5913    }
5914   
 
5915  19 toggle @Override
5916    public boolean equals(Object other) {
5917  1 if (this == other) return true;
5918  2 if (other == null || getClass() != other.getClass()) return false;
5919  16 MethodToken that = (MethodToken) other;
5920  16 return modifiers == that.modifiers
5921    && typeVariableAnnotationTokens.equals(that.typeVariableAnnotationTokens)
5922    && typeVariableBoundAnnotationTokens.equals(that.typeVariableBoundAnnotationTokens)
5923    && returnTypeAnnotationTokens.equals(that.returnTypeAnnotationTokens)
5924    && parameterTypeAnnotationTokens.equals(that.parameterTypeAnnotationTokens)
5925    && exceptionTypeAnnotationTokens.equals(that.exceptionTypeAnnotationTokens)
5926    && receiverTypeAnnotationTokens.equals(that.receiverTypeAnnotationTokens)
5927    && annotationTokens.equals(that.annotationTokens)
5928    && defaultValue.equals(that.defaultValue)
5929    && descriptor.equals(that.descriptor)
5930    && parameterTokens.equals(that.parameterTokens)
5931    && signatureResolution.equals(that.signatureResolution)
5932    && Arrays.equals(exceptionName, that.exceptionName)
5933    && name.equals(that.name)
5934    && parameterAnnotationTokens.equals(that.parameterAnnotationTokens);
5935    }
5936   
 
5937  17 toggle @Override
5938    public int hashCode() {
5939  17 int result = modifiers;
5940  17 result = 31 * result + name.hashCode();
5941  17 result = 31 * result + descriptor.hashCode();
5942  17 result = 31 * result + signatureResolution.hashCode();
5943  17 result = 31 * result + Arrays.hashCode(exceptionName);
5944  17 result = 31 * result + typeVariableAnnotationTokens.hashCode();
5945  17 result = 31 * result + typeVariableBoundAnnotationTokens.hashCode();
5946  17 result = 31 * result + returnTypeAnnotationTokens.hashCode();
5947  17 result = 31 * result + parameterTypeAnnotationTokens.hashCode();
5948  17 result = 31 * result + exceptionTypeAnnotationTokens.hashCode();
5949  17 result = 31 * result + receiverTypeAnnotationTokens.hashCode();
5950  17 result = 31 * result + annotationTokens.hashCode();
5951  17 result = 31 * result + parameterAnnotationTokens.hashCode();
5952  17 result = 31 * result + parameterTokens.hashCode();
5953  17 result = 31 * result + defaultValue.hashCode();
5954  17 return result;
5955    }
5956   
 
5957  17 toggle @Override
5958    public String toString() {
5959  17 return "TypePool.Default.LazyTypeDescription.MethodToken{" +
5960    "modifiers=" + modifiers +
5961    ", name='" + name + '\'' +
5962    ", descriptor='" + descriptor + '\'' +
5963    ", signatureResolution=" + signatureResolution +
5964    ", exceptionName=" + Arrays.toString(exceptionName) +
5965    ", typeVariableAnnotationTokens=" + typeVariableAnnotationTokens +
5966    ", typeVariableBoundAnnotationTokens=" + typeVariableBoundAnnotationTokens +
5967    ", returnTypeAnnotationTokens=" + returnTypeAnnotationTokens +
5968    ", parameterTypeAnnotationTokens=" + parameterTypeAnnotationTokens +
5969    ", exceptionTypeAnnotationTokens=" + exceptionTypeAnnotationTokens +
5970    ", receiverTypeAnnotationTokens=" + receiverTypeAnnotationTokens +
5971    ", annotationTokens=" + annotationTokens +
5972    ", parameterAnnotationTokens=" + parameterAnnotationTokens +
5973    ", parameterTokens=" + parameterTokens +
5974    ", defaultValue=" + defaultValue +
5975    '}';
5976    }
5977   
5978    /**
5979    * A token representing a method's parameter.
5980    */
 
5981    protected static class ParameterToken {
5982   
5983    /**
5984    * Donates an unknown name of a parameter.
5985    */
5986    protected static final String NO_NAME = null;
5987   
5988    /**
5989    * Donates an unknown modifier of a parameter.
5990    */
5991    protected static final Integer NO_MODIFIERS = null;
5992   
5993    /**
5994    * The name of the parameter or {@code null} if no explicit name for this parameter is known.
5995    */
5996    private final String name;
5997   
5998    /**
5999    * The modifiers of the parameter or {@code null} if no modifiers are known for this parameter.
6000    */
6001    private final Integer modifiers;
6002   
6003    /**
6004    * Creates a parameter token for a parameter without an explicit name and without specific modifiers.
6005    */
 
6006  100980 toggle protected ParameterToken() {
6007  100980 this(NO_NAME);
6008    }
6009   
6010    /**
6011    * Creates a parameter token for a parameter with an explicit name and without specific modifiers.
6012    *
6013    * @param name The name of the parameter.
6014    */
 
6015  103003 toggle protected ParameterToken(String name) {
6016  103003 this(name, NO_MODIFIERS);
6017    }
6018   
6019    /**
6020    * Creates a parameter token for a parameter with an explicit name and with specific modifiers.
6021    *
6022    * @param name The name of the parameter.
6023    * @param modifiers The modifiers of the parameter.
6024    */
 
6025  103215 toggle protected ParameterToken(String name, Integer modifiers) {
6026  103215 this.name = name;
6027  103215 this.modifiers = modifiers;
6028    }
6029   
6030    /**
6031    * Returns the name of the parameter or {@code null} if there is no such name.
6032    *
6033    * @return The name of the parameter or {@code null} if there is no such name.
6034    */
 
6035  2396 toggle protected String getName() {
6036  2396 return name;
6037    }
6038   
6039    /**
6040    * Returns the modifiers of the parameter or {@code null} if no modifiers are known.
6041    *
6042    * @return The modifiers of the parameter or {@code null} if no modifiers are known.
6043    */
 
6044  2396 toggle protected Integer getModifiers() {
6045  2396 return modifiers;
6046    }
6047   
 
6048  15 toggle @Override
6049    public boolean equals(Object other) {
6050  3 if (this == other) return true;
6051  6 if (other == null || getClass() != other.getClass()) return false;
6052  6 ParameterToken that = ((ParameterToken) other);
6053  6 return !(modifiers != null ? !modifiers.equals(that.modifiers) : that.modifiers != null)
6054  5 && !(name != null ? !name.equals(that.name) : that.name != null);
6055    }
6056   
 
6057  9 toggle @Override
6058    public int hashCode() {
6059  9 int result = name != null ? name.hashCode() : 0;
6060  9 result = 31 * result + (modifiers != null ? modifiers.hashCode() : 0);
6061  9 return result;
6062    }
6063   
 
6064  12 toggle @Override
6065    public String toString() {
6066  12 return "TypePool.Default.LazyTypeDescription.MethodToken.ParameterToken{" +
6067    "name='" + name + '\'' +
6068    ", modifiers=" + modifiers +
6069    '}';
6070    }
6071    }
6072    }
6073   
6074    /**
6075    * A lazy description of an annotation that looks up types from a type pool when required.
6076    */
 
6077    private static class LazyAnnotationDescription extends AnnotationDescription.AbstractBase {
6078   
6079    /**
6080    * The type pool for looking up type references.
6081    */
6082    protected final TypePool typePool;
6083   
6084    /**
6085    * The type of this annotation.
6086    */
6087    private final TypeDescription annotationType;
6088   
6089    /**
6090    * A map of annotation values by their property name.
6091    */
6092    protected final Map<String, AnnotationValue<?, ?>> values;
6093   
6094    /**
6095    * Creates a new lazy annotation description.
6096    *
6097    * @param typePool The type pool to be used for looking up linked types.
6098    * @param annotationType The annotation's type.
6099    * @param values A map of annotation value names to their value representations.
6100    */
 
6101  1805 toggle private LazyAnnotationDescription(TypePool typePool, TypeDescription annotationType, Map<String, AnnotationValue<?, ?>> values) {
6102  1805 this.typePool = typePool;
6103  1805 this.annotationType = annotationType;
6104  1805 this.values = values;
6105    }
6106   
6107    /**
6108    * Represents a list of annotation tokens in form of a list of lazy type annotations. Any annotation with
6109    * a type that cannot be loaded from the type pool is ignored and not included in the list. If the provided
6110    * {@code tokens} are {@code null}, an empty list is returned.
6111    *
6112    * @param typePool The type pool to be used for looking up linked types.
6113    * @param tokens The tokens to represent in the list.
6114    * @return A list of the loadable annotations.
6115    */
 
6116  1561 toggle protected static AnnotationList asListOfNullable(TypePool typePool, List<? extends AnnotationToken> tokens) {
6117  1561 return tokens == null
6118    ? new AnnotationList.Empty()
6119    : asList(typePool, tokens);
6120    }
6121   
6122    /**
6123    * Represents a list of annotation tokens in form of a list of lazy type annotations. Any annotation with
6124    * a type that cannot be loaded from the type pool is ignored and not included in the list.
6125    *
6126    * @param typePool The type pool to be used for looking up linked types.
6127    * @param tokens The tokens to represent in the list.
6128    * @return A list of the loadable annotations.
6129    */
 
6130  1690 toggle protected static AnnotationList asList(TypePool typePool, List<? extends AnnotationToken> tokens) {
6131  1690 List<AnnotationDescription> annotationDescriptions = new ArrayList<AnnotationDescription>(tokens.size());
6132  1690 for (AnnotationToken token : tokens) {
6133  1153 AnnotationToken.Resolution resolution = token.toAnnotationDescription(typePool);
6134  1153 if (resolution.isResolved()) {
6135  1147 annotationDescriptions.add(resolution.resolve());
6136    }
6137    }
6138  1690 return new AnnotationList.Explicit(annotationDescriptions);
6139    }
6140   
 
6141  850 toggle @Override
6142    public Object getValue(MethodDescription.InDefinedShape methodDescription) {
6143  850 if (!methodDescription.getDeclaringType().asErasure().equals(annotationType)) {
6144  1 throw new IllegalArgumentException(methodDescription + " is not declared by " + getAnnotationType());
6145    }
6146  849 AnnotationValue<?, ?> annotationValue = values.get(methodDescription.getName());
6147  849 Object value = annotationValue == null
6148    ? getAnnotationType().getDeclaredMethods().filter(is(methodDescription)).getOnly().getDefaultValue()
6149    : annotationValue.resolve();
6150  849 if (value == null) {
6151  0 throw new IllegalStateException(methodDescription + " is not defined on annotation");
6152    }
6153  849 return PropertyDispatcher.of(value.getClass()).conditionalClone(value);
6154    }
6155   
 
6156  1363 toggle @Override
6157    public TypeDescription getAnnotationType() {
6158  1363 return annotationType;
6159    }
6160   
 
6161  613 toggle @Override
6162    public <T extends Annotation> Loadable<T> prepare(Class<T> annotationType) {
6163  613 if (!this.annotationType.represents(annotationType)) {
6164  1 throw new IllegalArgumentException(annotationType + " does not represent " + this.annotationType);
6165    }
6166  612 return new Loadable<T>(typePool, annotationType, values);
6167    }
6168   
6169    /**
6170    * A loadable version of a lazy annotation description.
6171    *
6172    * @param <S> The annotation type.
6173    */
 
6174    private static class Loadable<S extends Annotation> extends LazyAnnotationDescription implements AnnotationDescription.Loadable<S> {
6175   
6176    /**
6177    * The loaded annotation type.
6178    */
6179    private final Class<S> annotationType;
6180   
6181    /**
6182    * Creates a new loadable version of a lazy annotation.
6183    *
6184    * @param typePool The type pool to be used for looking up linked types.
6185    * @param annotationType The annotation's loaded type.
6186    * @param values A map of annotation value names to their value representations.
6187    */
 
6188  612 toggle private Loadable(TypePool typePool, Class<S> annotationType, Map<String, AnnotationValue<?, ?>> values) {
6189  612 super(typePool, new ForLoadedType(annotationType), values);
6190  612 this.annotationType = annotationType;
6191    }
6192   
 
6193  116 toggle @Override
6194    public S load() throws ClassNotFoundException {
6195  116 return load(annotationType.getClassLoader());
6196    }
6197   
 
6198  116 toggle @Override
6199    @SuppressWarnings("unchecked")
6200    public S load(ClassLoader classLoader) throws ClassNotFoundException {
6201  116 return (S) Proxy.newProxyInstance(classLoader,
6202    new Class<?>[]{annotationType},
6203    AnnotationInvocationHandler.of(classLoader, annotationType, values));
6204    }
6205   
 
6206  2 toggle @Override
6207    public S loadSilent() {
6208  2 try {
6209  2 return load();
6210    } catch (ClassNotFoundException exception) {
6211  0 throw new IllegalStateException(ForLoadedAnnotation.ERROR_MESSAGE, exception);
6212    }
6213    }
6214   
 
6215  0 toggle @Override
6216    public S loadSilent(ClassLoader classLoader) {
6217  0 try {
6218  0 return load(classLoader);
6219    } catch (ClassNotFoundException exception) {
6220  0 throw new IllegalStateException(ForLoadedAnnotation.ERROR_MESSAGE, exception);
6221    }
6222    }
6223    }
6224    }
6225   
6226    /**
6227    * An implementation of a {@link PackageDescription} that only
6228    * loads its annotations on requirement.
6229    */
 
6230    private static class LazyPackageDescription extends PackageDescription.AbstractBase {
6231   
6232    /**
6233    * The type pool to use for look-ups.
6234    */
6235    private final TypePool typePool;
6236   
6237    /**
6238    * The name of the package.
6239    */
6240    private final String name;
6241   
6242    /**
6243    * Creates a new lazy package description.
6244    *
6245    * @param typePool The type pool to use for look-ups.
6246    * @param name The name of the package.
6247    */
 
6248  81 toggle private LazyPackageDescription(TypePool typePool, String name) {
6249  81 this.typePool = typePool;
6250  81 this.name = name;
6251    }
6252   
 
6253  2 toggle @Override
6254    public AnnotationList getDeclaredAnnotations() {
6255  2 Resolution resolution = typePool.describe(name + "." + PackageDescription.PACKAGE_CLASS_NAME);
6256  2 return resolution.isResolved()
6257    ? resolution.resolve().getDeclaredAnnotations()
6258    : new AnnotationList.Empty();
6259    }
6260   
 
6261  79 toggle @Override
6262    public String getName() {
6263  79 return name;
6264    }
6265    }
6266   
6267    /**
6268    * A list that is constructing {@link LazyTypeDescription}s.
6269    */
 
6270    private static class LazyTypeList extends TypeList.AbstractBase {
6271   
6272    /**
6273    * The type pool to use for locating types.
6274    */
6275    private final TypePool typePool;
6276   
6277    /**
6278    * A list of type descriptors that this list represents.
6279    */
6280    private final List<String> descriptors;
6281   
6282    /**
6283    * Creates a list of lazy type descriptions.
6284    *
6285    * @param typePool The type pool to use for locating types.
6286    * @param descriptors A list of type descriptors that this list represents.
6287    */
 
6288  1564 toggle private LazyTypeList(TypePool typePool, List<String> descriptors) {
6289  1564 this.typePool = typePool;
6290  1564 this.descriptors = descriptors;
6291    }
6292   
 
6293  1488 toggle @Override
6294    public TypeDescription get(int index) {
6295  1488 return TokenizedGenericType.toErasure(typePool, descriptors.get(index));
6296    }
6297   
 
6298  5279 toggle @Override
6299    public int size() {
6300  5279 return descriptors.size();
6301    }
6302   
 
6303  0 toggle @Override
6304    public String[] toInternalNames() {
6305  0 String[] internalName = new String[descriptors.size()];
6306  0 int index = 0;
6307  0 for (String descriptor : descriptors) {
6308  0 internalName[index++] = Type.getType(descriptor).getInternalName();
6309    }
6310  0 return internalName.length == 0
6311    ? NO_INTERFACES
6312    : internalName;
6313    }
6314   
 
6315  1 toggle @Override
6316    public int getStackSize() {
6317  1 int stackSize = 0;
6318  1 for (String descriptor : descriptors) {
6319  2 stackSize += Type.getType(descriptor).getSize();
6320    }
6321  1 return stackSize;
6322    }
6323    }
6324   
6325    /**
6326    * A representation of a generic type that is described by a {@link GenericTypeToken}.
6327    */
 
6328    private static class TokenizedGenericType extends Generic.LazyProjection {
6329   
6330    /**
6331    * The type pool to use for locating referenced types.
6332    */
6333    private final TypePool typePool;
6334   
6335    /**
6336    * The token that describes the represented generic type.
6337    */
6338    private final GenericTypeToken genericTypeToken;
6339   
6340    /**
6341    * A descriptor of the generic type's raw type.
6342    */
6343    private final String rawTypeDescriptor;
6344   
6345    /**
6346    * The tokenized type's type annotation tokens.
6347    */
6348    private final Map<String, List<AnnotationToken>> annotationTokens;
6349   
6350    /**
6351    * The closest type variable source of this generic type's declaration context.
6352    */
6353    private final TypeVariableSource typeVariableSource;
6354   
6355    /**
6356    * Creates a new tokenized generic type.
6357    *
6358    * @param typePool The type pool to use for locating referenced types.
6359    * @param genericTypeToken The token that describes the represented generic type.
6360    * @param rawTypeDescriptor A descriptor of the generic type's erasure.
6361    * @param annotationTokens The tokenized type's type annotation tokens.
6362    * @param typeVariableSource The closest type variable source of this generic type's declaration context.
6363    */
 
6364  1204 toggle protected TokenizedGenericType(TypePool typePool,
6365    GenericTypeToken genericTypeToken,
6366    String rawTypeDescriptor,
6367    Map<String, List<AnnotationToken>> annotationTokens,
6368    TypeVariableSource typeVariableSource) {
6369  1204 this.typePool = typePool;
6370  1204 this.genericTypeToken = genericTypeToken;
6371  1204 this.rawTypeDescriptor = rawTypeDescriptor;
6372  1204 this.annotationTokens = annotationTokens;
6373  1204 this.typeVariableSource = typeVariableSource;
6374    }
6375   
6376    /**
6377    * Creates a new generic type description for a tokenized generic type.
6378    *
6379    * @param typePool The type pool to use for locating referenced types.
6380    * @param genericTypeToken The token that describes the represented generic type.
6381    * @param rawTypeDescriptor A descriptor of the generic type's erasure.
6382    * @param annotationTokens The tokenized type's type annotation tokens or {@code null} if no such annotations are defined.
6383    * @param typeVariableSource The closest type variable source of this generic type's declaration context.
6384    * @return A suitable generic type.
6385    */
 
6386  1204 toggle protected static Generic of(TypePool typePool,
6387    GenericTypeToken genericTypeToken,
6388    String rawTypeDescriptor,
6389    Map<String, List<AnnotationToken>> annotationTokens,
6390    TypeVariableSource typeVariableSource) {
6391  1204 return new TokenizedGenericType(typePool,
6392    genericTypeToken,
6393    rawTypeDescriptor,
6394  1204 annotationTokens == null
6395    ? Collections.<String, List<AnnotationToken>>emptyMap()
6396    : annotationTokens,
6397    typeVariableSource);
6398    }
6399   
6400    /**
6401    * Creates a type description from a descriptor by looking up the corresponding type.
6402    *
6403    * @param typePool The type pool to use for locating a type.
6404    * @param descriptor The descriptor to interpret.
6405    * @return A description of the type represented by the descriptor.
6406    */
 
6407  4467 toggle protected static TypeDescription toErasure(TypePool typePool, String descriptor) {
6408  4467 Type type = Type.getType(descriptor);
6409  4467 return typePool.describe(type.getSort() == Type.ARRAY
6410    ? type.getInternalName().replace('/', '.')
6411    : type.getClassName()).resolve();
6412    }
6413   
 
6414  1585 toggle @Override
6415    protected Generic resolve() {
6416  1585 return genericTypeToken.toGenericType(typePool, typeVariableSource, GenericTypeToken.EMPTY_TYPE_PATH, annotationTokens);
6417    }
6418   
 
6419  510 toggle @Override
6420    public TypeDescription asErasure() {
6421  510 return toErasure(typePool, rawTypeDescriptor);
6422    }
6423   
 
6424  62 toggle @Override
6425    public AnnotationList getDeclaredAnnotations() {
6426  62 return resolve().getDeclaredAnnotations();
6427    }
6428   
6429    /**
6430    * A tokenized list of generic types.
6431    */
 
6432    protected static class TokenList extends TypeList.Generic.AbstractBase {
6433   
6434    /**
6435    * The type pool to use for locating types.
6436    */
6437    private final TypePool typePool;
6438   
6439    /**
6440    * Type tokens that describe the represented generic types.
6441    */
6442    private final List<GenericTypeToken> genericTypeTokens;
6443   
6444    /**
6445    * A list of the generic types' erasures.
6446    */
6447    private final List<String> rawTypeDescriptors;
6448   
6449    /**
6450    * The closest type variable source of this generic type's declaration context.
6451    */
6452    private final TypeVariableSource typeVariableSource;
6453   
6454    /**
6455    * A mapping of each type's type annotation tokens by its index.
6456    */
6457    private final Map<Integer, Map<String, List<AnnotationToken>>> annotationTokens;
6458   
6459    /**
6460    * Creates a list of tokenized generic types.
6461    *
6462    * @param typePool The type pool to use for locating type descriptions.
6463    * @param genericTypeTokens A list of tokens describing the represented generic types.
6464    * @param annotationTokens A mapping of each type's type annotation tokens by its index.
6465    * @param rawTypeDescriptors A list of the generic types' erasures.
6466    * @param typeVariableSource The closest type variable source of this generic type's declaration context.
6467    */
 
6468  588 toggle private TokenList(TypePool typePool,
6469    List<GenericTypeToken> genericTypeTokens,
6470    Map<Integer, Map<String, List<AnnotationToken>>> annotationTokens,
6471    List<String> rawTypeDescriptors,
6472    TypeVariableSource typeVariableSource) {
6473  588 this.typePool = typePool;
6474  588 this.genericTypeTokens = genericTypeTokens;
6475  588 this.annotationTokens = annotationTokens;
6476  588 this.rawTypeDescriptors = rawTypeDescriptors;
6477  588 this.typeVariableSource = typeVariableSource;
6478    }
6479   
 
6480  248 toggle @Override
6481    public Generic get(int index) {
6482  248 return rawTypeDescriptors.size() == genericTypeTokens.size()
6483    ? TokenizedGenericType.of(typePool, genericTypeTokens.get(index), rawTypeDescriptors.get(index), annotationTokens.get(index), typeVariableSource)
6484    : TokenizedGenericType.toErasure(typePool, rawTypeDescriptors.get(index)).asGenericType();
6485    }
6486   
 
6487  147 toggle @Override
6488    public int size() {
6489  147 return rawTypeDescriptors.size();
6490    }
6491   
 
6492  322 toggle @Override
6493    public TypeList asErasures() {
6494  322 return new LazyTypeList(typePool, rawTypeDescriptors);
6495    }
6496    }
6497   
6498    /**
6499    * A list of tokenized type variables.
6500    */
 
6501    protected static class TypeVariableList extends TypeList.Generic.AbstractBase {
6502   
6503    /**
6504    * The type pool to use for locating types.
6505    */
6506    private final TypePool typePool;
6507   
6508    /**
6509    * Type tokens that describe the represented type variables.
6510    */
6511    private final List<GenericTypeToken.OfFormalTypeVariable> typeVariables;
6512   
6513    /**
6514    * The type variable source of the represented type variables.
6515    */
6516    private final TypeVariableSource typeVariableSource;
6517   
6518    /**
6519    * A mapping of the type variables' type annotation tokens by their indices.
6520    */
6521    private final Map<Integer, Map<String, List<AnnotationToken>>> annotationTokens;
6522   
6523    /**
6524    * A mapping of the type variables' bound types' annotation tokens by their indices and each type variable's index..
6525    */
6526    private final Map<Integer, Map<Integer, Map<String, List<AnnotationToken>>>> boundAnnotationTokens;
6527   
6528    /**
6529    * Creates a list of type variables.
6530    *
6531    * @param typePool The type pool to use for locating types.
6532    * @param typeVariables Type tokens that describe the represented generic types.
6533    * @param typeVariableSource The type variable source of the represented type variables.
6534    * @param annotationTokens A mapping of the type variables' type annotation tokens by their indices.
6535    * @param boundAnnotationTokens A mapping of the type variables' bound types' annotation tokens by their indices
6536    * and each type variable's index.
6537    */
 
6538  1603 toggle protected TypeVariableList(TypePool typePool,
6539    List<GenericTypeToken.OfFormalTypeVariable> typeVariables,
6540    TypeVariableSource typeVariableSource,
6541    Map<Integer, Map<String, List<AnnotationToken>>> annotationTokens,
6542    Map<Integer, Map<Integer, Map<String, List<AnnotationToken>>>> boundAnnotationTokens) {
6543  1603 this.typePool = typePool;
6544  1603 this.typeVariables = typeVariables;
6545  1603 this.typeVariableSource = typeVariableSource;
6546  1603 this.annotationTokens = annotationTokens;
6547  1603 this.boundAnnotationTokens = boundAnnotationTokens;
6548    }
6549   
 
6550  2544 toggle @Override
6551    public Generic get(int index) {
6552  2544 return typeVariables.get(index).toGenericType(typePool, typeVariableSource, annotationTokens.get(index), boundAnnotationTokens.get(index));
6553    }
6554   
 
6555  7695 toggle @Override
6556    public int size() {
6557  7695 return typeVariables.size();
6558    }
6559    }
6560   
6561    /**
6562    * A lazy description of a non-well-defined described generic type.
6563    */
 
6564    protected static class Malformed extends LazyProjection {
6565   
6566    /**
6567    * The type pool to use for locating types.
6568    */
6569    private final TypePool typePool;
6570   
6571    /**
6572    * The descriptor of the type erasure.
6573    */
6574    private final String rawTypeDescriptor;
6575   
6576    /**
6577    * Creates a lazy description of a non-well-defined described generic type.
6578    *
6579    * @param typePool The type pool to use for locating types.
6580    * @param rawTypeDescriptor The descriptor of the type erasure.
6581    */
 
6582  6 toggle protected Malformed(TypePool typePool, String rawTypeDescriptor) {
6583  6 this.typePool = typePool;
6584  6 this.rawTypeDescriptor = rawTypeDescriptor;
6585    }
6586   
 
6587  6 toggle @Override
6588    protected Generic resolve() {
6589  6 throw new GenericSignatureFormatError();
6590    }
6591   
 
6592  0 toggle @Override
6593    public TypeDescription asErasure() {
6594  0 return toErasure(typePool, rawTypeDescriptor);
6595    }
6596   
 
6597  0 toggle @Override
6598    public AnnotationList getDeclaredAnnotations() {
6599  0 throw new GenericSignatureFormatError();
6600    }
6601   
6602    /**
6603    * A tokenized list of non-well-defined generic types.
6604    */
 
6605    protected static class TokenList extends TypeList.Generic.AbstractBase {
6606   
6607    /**
6608    * The type pool to use for locating types.
6609    */
6610    private final TypePool typePool;
6611   
6612    /**
6613    * A list of descriptors of the list's types' erasures.
6614    */
6615    private final List<String> rawTypeDescriptors;
6616   
6617    /**
6618    * Creates a new tokenized list of generic types.
6619    *
6620    * @param typePool The type pool to use for locating types.
6621    * @param rawTypeDescriptors A list of descriptors of the list's types' erasures.
6622    */
 
6623  4 toggle protected TokenList(TypePool typePool, List<String> rawTypeDescriptors) {
6624  4 this.typePool = typePool;
6625  4 this.rawTypeDescriptors = rawTypeDescriptors;
6626    }
6627   
 
6628  2 toggle @Override
6629    public Generic get(int index) {
6630  2 return new Malformed(typePool, rawTypeDescriptors.get(index));
6631    }
6632   
 
6633  4 toggle @Override
6634    public int size() {
6635  4 return rawTypeDescriptors.size();
6636    }
6637   
 
6638  0 toggle @Override
6639    public TypeList asErasures() {
6640  0 return new LazyTypeList(typePool, rawTypeDescriptors);
6641    }
6642    }
6643   
6644    }
6645    }
6646   
6647    /**
6648    * A lazy field description that only resolved type references when required.
6649    */
 
6650    private class LazyFieldDescription extends FieldDescription.InDefinedShape.AbstractBase {
6651   
6652    /**
6653    * The name of the field.
6654    */
6655    private final String name;
6656   
6657    /**
6658    * The modifiers of the field.
6659    */
6660    private final int modifiers;
6661   
6662    /**
6663    * The descriptor of this field's type.
6664    */
6665    private final String descriptor;
6666   
6667    /**
6668    * A resolution of this field's generic type.
6669    */
6670    private final GenericTypeToken.Resolution.ForField signatureResolution;
6671   
6672    /**
6673    * A mapping of the field type's type annotation tokens.
6674    */
6675    private final Map<String, List<AnnotationToken>> typeAnnotationTokens;
6676   
6677    /**
6678    * A list of annotation descriptions of this field.
6679    */
6680    private final List<AnnotationToken> annotationTokens;
6681   
6682    /**
6683    * Creates a new lazy field description.
6684    *
6685    * @param name The name of the field.
6686    * @param modifiers The modifiers of the field.
6687    * @param descriptor The descriptor of this field's type.
6688    * @param signatureResolution A resolution of this field's generic type.
6689    * @param typeAnnotationTokens A mapping of the field type's type annotation tokens.
6690    * @param annotationTokens A list of annotation descriptions of this field.
6691    */
 
6692  829 toggle private LazyFieldDescription(String name,
6693    int modifiers,
6694    String descriptor,
6695    GenericTypeToken.Resolution.ForField signatureResolution,
6696    Map<String, List<AnnotationToken>> typeAnnotationTokens,
6697    List<AnnotationToken> annotationTokens) {
6698  829 this.modifiers = modifiers & ~Opcodes.ACC_DEPRECATED;
6699  829 this.name = name;
6700  829 this.descriptor = descriptor;
6701  829 this.signatureResolution = signatureResolution;
6702  829 this.typeAnnotationTokens = typeAnnotationTokens;
6703  829 this.annotationTokens = annotationTokens;
6704    }
6705   
 
6706  300 toggle @Override
6707    public Generic getType() {
6708  300 return signatureResolution.resolveFieldType(descriptor, typePool, typeAnnotationTokens, this);
6709    }
6710   
 
6711  47 toggle @Override
6712    public AnnotationList getDeclaredAnnotations() {
6713  47 return LazyAnnotationDescription.asListOfNullable(typePool, annotationTokens);
6714    }
6715   
 
6716  628 toggle @Override
6717    public String getName() {
6718  628 return name;
6719    }
6720   
 
6721  551 toggle @Override
6722    public TypeDescription getDeclaringType() {
6723  551 return LazyTypeDescription.this;
6724    }
6725   
 
6726  89 toggle @Override
6727    public int getModifiers() {
6728  89 return modifiers;
6729    }
6730    }
6731   
6732    /**
6733    * A lazy representation of a method that resolves references to types only on demand.
6734    */
 
6735    private class LazyMethodDescription extends MethodDescription.InDefinedShape.AbstractBase {
6736   
6737    /**
6738    * The internal name of this method.
6739    */
6740    private final String internalName;
6741   
6742    /**
6743    * The modifiers of this method.
6744    */
6745    private final int modifiers;
6746   
6747    /**
6748    * The descriptor of the return type.
6749    */
6750    private final String returnTypeDescriptor;
6751   
6752    /**
6753    * The generic type token of this method.
6754    */
6755    private final GenericTypeToken.Resolution.ForMethod signatureResolution;
6756   
6757    /**
6758    * A list of type descriptions of this method's parameters.
6759    */
6760    private final List<String> parameterTypeDescriptors;
6761   
6762    /**
6763    * A list of type descriptions of this method's exception types.
6764    */
6765    private final List<String> exceptionTypeDescriptors;
6766   
6767    /**
6768    * A mapping of the type variables' type annotation tokens by their indices.
6769    */
6770    private final Map<Integer, Map<String, List<AnnotationToken>>> typeVariableAnnotationTokens;
6771   
6772    /**
6773    * A mapping of the type variables' type bounds' type annotation tokens by their indices and each variable's index.
6774    */
6775    private final Map<Integer, Map<Integer, Map<String, List<AnnotationToken>>>> typeVariableBoundAnnotationTokens;
6776   
6777    /**
6778    * A mapping of the return type's type variable tokens.
6779    */
6780    private final Map<String, List<AnnotationToken>> returnTypeAnnotationTokens;
6781   
6782    /**
6783    * A mapping of the parameter types' type annotation tokens by their indices.
6784    */
6785    private final Map<Integer, Map<String, List<AnnotationToken>>> parameterTypeAnnotationTokens;
6786   
6787    /**
6788    * A mapping of the exception types' type annotation tokens by their indices.
6789    */
6790    private final Map<Integer, Map<String, List<AnnotationToken>>> exceptionTypeAnnotationTokens;
6791   
6792    /**
6793    * A mapping of the receiver type's type annotation tokens.
6794    */
6795    private final Map<String, List<AnnotationToken>> receiverTypeAnnotationTokens;
6796   
6797    /**
6798    * The annotation tokens representing the method's annotations.
6799    */
6800    private final List<AnnotationToken> annotationTokens;
6801   
6802    /**
6803    * The annotation tokens representing the parameter's annotation. Every index can
6804    * contain {@code null} if a parameter does not define any annotations.
6805    */
6806    private final Map<Integer, List<AnnotationToken>> parameterAnnotationTokens;
6807   
6808    /**
6809    * An array of parameter names which may be {@code null} if no explicit name is known for a parameter.
6810    */
6811    private final String[] parameterNames;
6812   
6813    /**
6814    * An array of parameter modifiers which may be {@code null} if no modifiers is known.
6815    */
6816    private final Integer[] parameterModifiers;
6817   
6818    /**
6819    * The default value of this method or {@code null} if no such value exists.
6820    */
6821    private final AnnotationDescription.AnnotationValue<?, ?> defaultValue;
6822   
6823    /**
6824    * Creates a new lazy method description.
6825    *
6826    * @param internalName The internal name of this method.
6827    * @param modifiers The modifiers of the represented method.
6828    * @param methodDescriptor The method descriptor of this method.
6829    * @param signatureResolution The generic type token of this method.
6830    * @param exceptionTypeInternalName The internal names of the exceptions that are declared by this
6831    * method or {@code null} if no exceptions are declared by this
6832    * method.
6833    * @param typeVariableAnnotationTokens A mapping of the type variables' type annotation tokens by their indices.
6834    * @param typeVariableBoundAnnotationTokens A mapping of the type variables' type bounds' type annotation tokens by their
6835    * index and each variable's index.
6836    * @param returnTypeAnnotationTokens A mapping of the return type's type variable tokens.
6837    * @param parameterTypeAnnotationTokens A mapping of the parameter types' type annotation tokens by their indices.
6838    * @param exceptionTypeAnnotationTokens A mapping of the exception types' type annotation tokens by their indices.
6839    * @param receiverTypeAnnotationTokens A mapping of the receiver type's type annotation tokens.
6840    * @param annotationTokens The annotation tokens representing the method's annotations.
6841    * @param parameterAnnotationTokens The annotation tokens representing the parameter's annotation. Every
6842    * index can contain {@code null} if a parameter does not define any annotations.
6843    * @param parameterTokens A list of parameter tokens which might be empty or even out of sync
6844    * with the actual parameters if the debugging information found in a
6845    * class was corrupt.
6846    * @param defaultValue The default value of this method or {@code null} if there is no
6847    */
 
6848  14863 toggle @SuppressFBWarnings(value = "URF_UNREAD_FIELD", justification = "To be removed once type annotations are in place")
6849    private LazyMethodDescription(String internalName,
6850    int modifiers,
6851    String methodDescriptor,
6852    GenericTypeToken.Resolution.ForMethod signatureResolution,
6853    String[] exceptionTypeInternalName,
6854    Map<Integer, Map<String, List<AnnotationToken>>> typeVariableAnnotationTokens,
6855    Map<Integer, Map<Integer, Map<String, List<AnnotationToken>>>> typeVariableBoundAnnotationTokens,
6856    Map<String, List<AnnotationToken>> returnTypeAnnotationTokens,
6857    Map<Integer, Map<String, List<AnnotationToken>>> parameterTypeAnnotationTokens,
6858    Map<Integer, Map<String, List<AnnotationToken>>> exceptionTypeAnnotationTokens,
6859    Map<String, List<AnnotationToken>> receiverTypeAnnotationTokens,
6860    List<AnnotationToken> annotationTokens,
6861    Map<Integer, List<AnnotationToken>> parameterAnnotationTokens,
6862    List<MethodToken.ParameterToken> parameterTokens,
6863    AnnotationDescription.AnnotationValue<?, ?> defaultValue) {
6864  14863 this.modifiers = modifiers & ~Opcodes.ACC_DEPRECATED;
6865  14863 this.internalName = internalName;
6866  14863 Type methodType = Type.getMethodType(methodDescriptor);
6867  14863 Type returnType = methodType.getReturnType();
6868  14863 Type[] parameterType = methodType.getArgumentTypes();
6869  14863 returnTypeDescriptor = returnType.getDescriptor();
6870  14863 parameterTypeDescriptors = new ArrayList<String>(parameterType.length);
6871  14863 for (Type type : parameterType) {
6872  2384 parameterTypeDescriptors.add(type.getDescriptor());
6873    }
6874  14863 this.signatureResolution = signatureResolution;
6875  14863 if (exceptionTypeInternalName == null) {
6876  13387 exceptionTypeDescriptors = Collections.emptyList();
6877    } else {
6878  1476 exceptionTypeDescriptors = new ArrayList<String>(exceptionTypeInternalName.length);
6879  1476 for (String anExceptionTypeInternalName : exceptionTypeInternalName) {
6880  1774 exceptionTypeDescriptors.add(Type.getObjectType(anExceptionTypeInternalName).getDescriptor());
6881    }
6882    }
6883  14863 this.typeVariableAnnotationTokens = typeVariableAnnotationTokens;
6884  14863 this.typeVariableBoundAnnotationTokens = typeVariableBoundAnnotationTokens;
6885  14863 this.returnTypeAnnotationTokens = returnTypeAnnotationTokens;
6886  14863 this.parameterTypeAnnotationTokens = parameterTypeAnnotationTokens;
6887  14863 this.exceptionTypeAnnotationTokens = exceptionTypeAnnotationTokens;
6888  14863 this.receiverTypeAnnotationTokens = receiverTypeAnnotationTokens;
6889  14863 this.annotationTokens = annotationTokens;
6890  14863 this.parameterAnnotationTokens = parameterAnnotationTokens;
6891  14863 parameterNames = new String[parameterType.length];
6892  14863 parameterModifiers = new Integer[parameterType.length];
6893  14863 if (parameterTokens.size() == parameterType.length) {
6894  14863 int index = 0;
6895  14863 for (MethodToken.ParameterToken parameterToken : parameterTokens) {
6896  2384 parameterNames[index] = parameterToken.getName();
6897  2384 parameterModifiers[index] = parameterToken.getModifiers();
6898  2384 index++;
6899    }
6900    }
6901  14863 this.defaultValue = defaultValue;
6902    }
6903   
 
6904  2349 toggle @Override
6905    public Generic getReturnType() {
6906  2349 return signatureResolution.resolveReturnType(returnTypeDescriptor, typePool, returnTypeAnnotationTokens, this);
6907    }
6908   
 
6909  463 toggle @Override
6910    public TypeList.Generic getExceptionTypes() {
6911  463 return signatureResolution.resolveExceptionTypes(exceptionTypeDescriptors, typePool, exceptionTypeAnnotationTokens, this);
6912    }
6913   
 
6914  1914 toggle @Override
6915    public ParameterList<ParameterDescription.InDefinedShape> getParameters() {
6916  1914 return new LazyParameterList();
6917    }
6918   
 
6919  435 toggle @Override
6920    public AnnotationList getDeclaredAnnotations() {
6921  435 return LazyAnnotationDescription.asList(typePool, annotationTokens);
6922    }
6923   
 
6924  64790 toggle @Override
6925    public String getInternalName() {
6926  64790 return internalName;
6927    }
6928   
 
6929  1420 toggle @Override
6930    public TypeDescription getDeclaringType() {
6931  1420 return LazyTypeDescription.this;
6932    }
6933   
 
6934  2172 toggle @Override
6935    public int getModifiers() {
6936  2172 return modifiers;
6937    }
6938   
 
6939  1042 toggle @Override
6940    public TypeList.Generic getTypeVariables() {
6941  1042 return signatureResolution.resolveTypeVariables(typePool, this, typeVariableAnnotationTokens, typeVariableBoundAnnotationTokens);
6942    }
6943   
 
6944  466 toggle @Override
6945    public Object getDefaultValue() {
6946  466 return defaultValue == null
6947    ? NO_DEFAULT_VALUE
6948    : defaultValue.resolve();
6949    }
6950   
 
6951  452 toggle @Override
6952    public Generic getReceiverType() {
6953  452 if (isStatic()) {
6954  33 return Generic.UNDEFINED;
6955  419 } else if (isConstructor()) {
6956  174 TypeDescription declaringType = getDeclaringType(), enclosingDeclaringType = declaringType.getEnclosingType();
6957  174 if (enclosingDeclaringType == null) {
6958  70 return declaringType.isGenericDeclaration()
6959    ? new LazyParameterizedReceiverType(declaringType)
6960    : new LazyNonGenericReceiverType(declaringType);
6961    } else {
6962  104 return !declaringType.isStatic() && declaringType.isGenericDeclaration()
6963    ? new LazyParameterizedReceiverType(enclosingDeclaringType)
6964    : new LazyNonGenericReceiverType(enclosingDeclaringType);
6965    }
6966    } else {
6967  245 return LazyTypeDescription.this.isGenericDeclaration()
6968    ? new LazyParameterizedReceiverType()
6969    : new LazyNonGenericReceiverType();
6970    }
6971    }
6972   
6973    /**
6974    * A lazy list of parameter descriptions for the enclosing method description.
6975    */
 
6976    private class LazyParameterList extends ParameterList.AbstractBase<ParameterDescription.InDefinedShape> {
6977   
 
6978  443 toggle @Override
6979    public ParameterDescription.InDefinedShape get(int index) {
6980  443 return new LazyParameterDescription(index);
6981    }
6982   
 
6983  0 toggle @Override
6984    public boolean hasExplicitMetaData() {
6985  0 for (int i = 0; i < size(); i++) {
6986  0 if (parameterNames[i] == null || parameterModifiers[i] == null) {
6987  0 return false;
6988    }
6989    }
6990  0 return true;
6991    }
6992   
 
6993  1966 toggle @Override
6994    public int size() {
6995  1966 return parameterTypeDescriptors.size();
6996    }
6997   
 
6998  977 toggle @Override
6999    public TypeList.Generic asTypeList() {
7000  977 return signatureResolution.resolveParameterTypes(parameterTypeDescriptors, typePool, parameterTypeAnnotationTokens, LazyMethodDescription.this);
7001    }
7002    }
7003   
7004    /**
7005    * A lazy description of a parameters of the enclosing method.
7006    */
 
7007    private class LazyParameterDescription extends ParameterDescription.InDefinedShape.AbstractBase {
7008   
7009    /**
7010    * The index of the described parameter.
7011    */
7012    private final int index;
7013   
7014    /**
7015    * Creates a new description for a given parameter of the enclosing method.
7016    *
7017    * @param index The index of the described parameter.
7018    */
 
7019  443 toggle protected LazyParameterDescription(int index) {
7020  443 this.index = index;
7021    }
7022   
 
7023  18 toggle @Override
7024    public MethodDescription.InDefinedShape getDeclaringMethod() {
7025  18 return LazyMethodDescription.this;
7026    }
7027   
 
7028  21 toggle @Override
7029    public int getIndex() {
7030  21 return index;
7031    }
7032   
 
7033  184 toggle @Override
7034    public boolean isNamed() {
7035  184 return parameterNames[index] != null;
7036    }
7037   
 
7038  177 toggle @Override
7039    public boolean hasModifiers() {
7040  177 return parameterModifiers[index] != null;
7041    }
7042   
 
7043  40 toggle @Override
7044    public String getName() {
7045  40 return isNamed()
7046    ? parameterNames[index]
7047    : super.getName();
7048    }
7049   
 
7050  44 toggle @Override
7051    public int getModifiers() {
7052  44 return hasModifiers()
7053    ? parameterModifiers[index]
7054    : super.getModifiers();
7055    }
7056   
 
7057  378 toggle @Override
7058    public Generic getType() {
7059  378 return signatureResolution.resolveParameterTypes(parameterTypeDescriptors, typePool, parameterTypeAnnotationTokens, LazyMethodDescription.this).get(index);
7060    }
7061   
 
7062  140 toggle @Override
7063    public AnnotationList getDeclaredAnnotations() {
7064  140 return LazyAnnotationDescription.asListOfNullable(typePool, parameterAnnotationTokens.get(index));
7065    }
7066    }
7067   
7068    /**
7069    * A lazy description of a parameterized receiver type.
7070    */
 
7071    private class LazyParameterizedReceiverType extends Generic.OfParameterizedType {
7072   
7073    /**
7074    * The erasure of the type to be represented as a parameterized receiver type.
7075    */
7076    private final TypeDescription typeDescription;
7077   
7078    /**
7079    * Creates a new lazy parameterized receiver type of the method's declaring type.
7080    */
 
7081  6 toggle protected LazyParameterizedReceiverType() {
7082  6 this(LazyTypeDescription.this);
7083    }
7084   
7085    /**
7086    * Creates a new lazy parameterized receiver type of the supplied receiver type.
7087    *
7088    * @param typeDescription The erasure of the type to be represented as a parameterized receiver type.
7089    */
 
7090  32 toggle protected LazyParameterizedReceiverType(TypeDescription typeDescription) {
7091  32 this.typeDescription = typeDescription;
7092    }
7093   
 
7094  46 toggle @Override
7095    public TypeList.Generic getTypeArguments() {
7096  46 return new TypeArgumentList(typeDescription.getTypeVariables());
7097    }
7098   
 
7099  40 toggle @Override
7100    public Generic getOwnerType() {
7101  40 TypeDescription declaringType = typeDescription.getDeclaringType();
7102  40 if (declaringType == null) {
7103  0 return UNDEFINED;
7104    } else {
7105  40 return !typeDescription.isStatic() && declaringType.isGenericDeclaration()
7106    ? new LazyParameterizedReceiverType(declaringType)
7107    : new LazyNonGenericReceiverType(declaringType);
7108    }
7109    }
7110   
 
7111  30 toggle @Override
7112    public AnnotationList getDeclaredAnnotations() {
7113  30 return LazyAnnotationDescription.asListOfNullable(typePool, receiverTypeAnnotationTokens.get(getTypePath()));
7114    }
7115   
7116    /**
7117    * Returns the type path for this type.
7118    *
7119    * @return This type's type path.
7120    */
 
7121  60 toggle private String getTypePath() {
7122  60 StringBuilder typePath = new StringBuilder();
7123  72 for (int index = 0; index < typeDescription.getSegmentCount(); index++) {
7124  12 typePath = typePath.append(GenericTypeToken.INNER_CLASS_PATH);
7125    }
7126  60 return typePath.toString();
7127    }
7128   
 
7129  10 toggle @Override
7130    public TypeDescription asErasure() {
7131  10 return typeDescription;
7132    }
7133   
7134    /**
7135    * A list of generic types representing the receiver type's type arguments.
7136    */
 
7137    protected class TypeArgumentList extends TypeList.Generic.AbstractBase {
7138   
7139    /**
7140    * The type variables of the represented receiver type.
7141    */
7142    private final List<? extends Generic> typeVariables;
7143   
7144    /**
7145    * Creates a new type argument list.
7146    *
7147    * @param typeVariables The type variables of the represented receiver type.
7148    */
 
7149  46 toggle protected TypeArgumentList(List<? extends Generic> typeVariables) {
7150  46 this.typeVariables = typeVariables;
7151    }
7152   
 
7153  46 toggle @Override
7154    public Generic get(int index) {
7155  46 return new AnnotatedTypeVariable(typeVariables.get(index), index);
7156    }
7157   
 
7158  46 toggle @Override
7159    public int size() {
7160  46 return typeVariables.size();
7161    }
7162   
7163    /**
7164    * Represents a type variable as a type argument with type annotations.
7165    */
 
7166    protected class AnnotatedTypeVariable extends OfTypeVariable {
7167   
7168    /**
7169    * The type variable's description.
7170    */
7171    private final Generic typeVariable;
7172   
7173    /**
7174    * The type variable's index.
7175    */
7176    private final int index;
7177   
7178    /**
7179    * Creates a new description of an annotated type variable as a type argument.
7180    *
7181    * @param typeVariable The type variable's description.
7182    * @param index The type variable's index.
7183    */
 
7184  46 toggle protected AnnotatedTypeVariable(Generic typeVariable, int index) {
7185  46 this.typeVariable = typeVariable;
7186  46 this.index = index;
7187    }
7188   
 
7189  0 toggle @Override
7190    public TypeList.Generic getUpperBounds() {
7191  0 return typeVariable.getUpperBounds();
7192    }
7193   
 
7194  0 toggle @Override
7195    public TypeVariableSource getVariableSource() {
7196  0 return typeVariable.getVariableSource();
7197    }
7198   
 
7199  8 toggle @Override
7200    public String getSymbol() {
7201  8 return typeVariable.getSymbol();
7202    }
7203   
 
7204  30 toggle @Override
7205    public AnnotationList getDeclaredAnnotations() {
7206  30 return LazyAnnotationDescription.asListOfNullable(typePool, receiverTypeAnnotationTokens.get(getTypePath()
7207    + index
7208    + GenericTypeToken.INDEXED_TYPE_DELIMITER));
7209    }
7210    }
7211    }
7212    }
7213   
7214    /**
7215    * A lazy description of a non-generic receiver type.
7216    */
 
7217    protected class LazyNonGenericReceiverType extends Generic.OfNonGenericType {
7218   
7219    /**
7220    * The type description of the non-generic receiver type.
7221    */
7222    private final TypeDescription typeDescription;
7223   
7224    /**
7225    * Creates a new non-generic receiver type of the method's declaring type.
7226    */
 
7227  239 toggle protected LazyNonGenericReceiverType() {
7228  239 this(LazyTypeDescription.this);
7229    }
7230   
7231    /**
7232    * Creates a new non-generic receiver type of the supplied type.
7233    *
7234    * @param typeDescription The type to represent as a non-generic receiver type.
7235    */
 
7236  571 toggle protected LazyNonGenericReceiverType(TypeDescription typeDescription) {
7237  571 this.typeDescription = typeDescription;
7238    }
7239   
 
7240  320 toggle @Override
7241    public Generic getOwnerType() {
7242  320 TypeDescription declaringType = typeDescription.getDeclaringType();
7243  320 return declaringType == null
7244    ? UNDEFINED
7245    : new LazyNonGenericReceiverType(declaringType);
7246    }
7247   
 
7248  0 toggle @Override
7249    public Generic getComponentType() {
7250  0 return UNDEFINED;
7251    }
7252   
 
7253  330 toggle @Override
7254    public AnnotationList getDeclaredAnnotations() {
7255  330 StringBuilder typePath = new StringBuilder();
7256  336 for (int index = 0; index < typeDescription.getSegmentCount(); index++) {
7257  6 typePath = typePath.append(GenericTypeToken.INNER_CLASS_PATH);
7258    }
7259  330 return LazyAnnotationDescription.asListOfNullable(typePool, receiverTypeAnnotationTokens.get(typePath.toString()));
7260    }
7261   
 
7262  1408 toggle @Override
7263    public TypeDescription asErasure() {
7264  1408 return typeDescription;
7265    }
7266    }
7267    }
7268    }
7269   
7270    /**
7271    * A type extractor reads a class file and collects data that is relevant to create a type description.
7272    */
 
7273    protected class TypeExtractor extends ClassVisitor {
7274   
7275    /**
7276    * A mask that cuts off pseudo flags beyond the second byte that are inserted by ASM.
7277    */
7278    private static final int REAL_MODIFIER_MASK = 0xFFFF;
7279   
7280    /**
7281    * A mapping of the super types' type annotation tokens by their indices.
7282    */
7283    private final Map<Integer, Map<String, List<LazyTypeDescription.AnnotationToken>>> superTypeAnnotationTokens;
7284   
7285    /**
7286    * A mapping of the type variables' type annotation tokens by their indices.
7287    */
7288    private final Map<Integer, Map<String, List<LazyTypeDescription.AnnotationToken>>> typeVariableAnnotationTokens;
7289   
7290    /**
7291    * A mapping of the type variables' bounds' type annotation tokens by their indices and each variables index.
7292    */
7293    private final Map<Integer, Map<Integer, Map<String, List<LazyTypeDescription.AnnotationToken>>>> typeVariableBoundsAnnotationTokens;
7294   
7295    /**
7296    * A list of annotation tokens describing annotations that are found on the visited type.
7297    */
7298    private final List<LazyTypeDescription.AnnotationToken> annotationTokens;
7299   
7300    /**
7301    * A list of field tokens describing fields that are found on the visited type.
7302    */
7303    private final List<LazyTypeDescription.FieldToken> fieldTokens;
7304   
7305    /**
7306    * A list of method tokens describing annotations that are found on the visited type.
7307    */
7308    private final List<LazyTypeDescription.MethodToken> methodTokens;
7309   
7310    /**
7311    * The modifiers found for this type.
7312    */
7313    private int modifiers;
7314   
7315    /**
7316    * The internal name found for this type.
7317    */
7318    private String internalName;
7319   
7320    /**
7321    * The internal name of the super type found for this type or {@code null} if no such type exists.
7322    */
7323    private String superClassName;
7324   
7325    /**
7326    * The generic signature of the type or {@code null} if it is not generic.
7327    */
7328    private String genericSignature;
7329   
7330    /**
7331    * A list of internal names of interfaces implemented by this type or {@code null} if no interfaces
7332    * are implemented.
7333    */
7334    private String[] interfaceName;
7335   
7336    /**
7337    * {@code true} if this type was found to represent an anonymous type.
7338    */
7339    private boolean anonymousType;
7340   
7341    /**
7342    * The declaration context found for this type.
7343    */
7344    private LazyTypeDescription.DeclarationContext declarationContext;
7345   
7346    /**
7347    * A list of descriptors representing the types that are declared by the parsed type.
7348    */
7349    private final List<String> declaredTypes;
7350   
7351    /**
7352    * Creates a new type extractor.
7353    */
 
7354  4977 toggle protected TypeExtractor() {
7355  4977 super(Opcodes.ASM5);
7356  4977 superTypeAnnotationTokens = new HashMap<Integer, Map<String, List<LazyTypeDescription.AnnotationToken>>>();
7357  4977 typeVariableAnnotationTokens = new HashMap<Integer, Map<String, List<LazyTypeDescription.AnnotationToken>>>();
7358  4977 typeVariableBoundsAnnotationTokens = new HashMap<Integer, Map<Integer, Map<String, List<LazyTypeDescription.AnnotationToken>>>>();
7359  4977 annotationTokens = new ArrayList<LazyTypeDescription.AnnotationToken>();
7360  4977 fieldTokens = new ArrayList<LazyTypeDescription.FieldToken>();
7361  4977 methodTokens = new ArrayList<LazyTypeDescription.MethodToken>();
7362  4977 anonymousType = false;
7363  4977 declarationContext = LazyTypeDescription.DeclarationContext.SelfDeclared.INSTANCE;
7364  4977 declaredTypes = new ArrayList<String>();
7365    }
7366   
 
7367  4977 toggle @Override
7368    @SuppressFBWarnings(value = "EI_EXPOSE_REP2", justification = "The received value is never modified")
7369    public void visit(int classFileVersion,
7370    int modifiers,
7371    String internalName,
7372    String genericSignature,
7373    String superClassName,
7374    String[] interfaceName) {
7375  4977 this.modifiers = modifiers & REAL_MODIFIER_MASK;
7376  4977 this.internalName = internalName;
7377  4977 this.genericSignature = genericSignature;
7378  4977 this.superClassName = superClassName;
7379  4977 this.interfaceName = interfaceName;
7380    }
7381   
 
7382  61 toggle @Override
7383    public void visitOuterClass(String typeName, String methodName, String methodDescriptor) {
7384  61 if (methodName != null) {
7385  61 declarationContext = new LazyTypeDescription.DeclarationContext.DeclaredInMethod(typeName, methodName, methodDescriptor);
7386  0 } else if (typeName != null) {
7387  0 declarationContext = new LazyTypeDescription.DeclarationContext.DeclaredInType(typeName);
7388    }
7389    }
7390   
 
7391  14656 toggle @Override
7392    public void visitInnerClass(String internalName, String outerName, String innerName, int modifiers) {
7393  14656 if (internalName.equals(this.internalName)) {
7394  1947 this.modifiers = modifiers & REAL_MODIFIER_MASK;
7395  1947 if (innerName == null) {
7396  19 anonymousType = true;
7397    }
7398    // Older Java compilers do not add the outer class attribute.
7399  1947 if (outerName != null && declarationContext.isSelfDeclared()) {
7400  1886 declarationContext = new LazyTypeDescription.DeclarationContext.DeclaredInType(outerName);
7401    }
7402  12709 } else if (outerName != null && innerName != null && internalName.equals(this.internalName + "$" + innerName)) {
7403  6064 declaredTypes.add("L" + internalName + ";");
7404    }
7405    }
7406   
 
7407  798 toggle @Override
7408    public AnnotationVisitor visitTypeAnnotation(int rawTypeReference, TypePath typePath, String descriptor, boolean visible) {
7409  798 AnnotationRegistrant annotationRegistrant;
7410  798 TypeReference typeReference = new TypeReference(rawTypeReference);
7411  798 switch (typeReference.getSort()) {
7412  152 case TypeReference.CLASS_EXTENDS:
7413  152 annotationRegistrant = new AnnotationRegistrant.ForTypeVariable.WithIndex(descriptor,
7414    typePath,
7415    typeReference.getSuperTypeIndex(),
7416    superTypeAnnotationTokens);
7417  152 break;
7418  190 case TypeReference.CLASS_TYPE_PARAMETER:
7419  190 annotationRegistrant = new AnnotationRegistrant.ForTypeVariable.WithIndex(descriptor,
7420    typePath,
7421    typeReference.getTypeParameterIndex(),
7422    typeVariableAnnotationTokens);
7423  190 break;
7424  456 case TypeReference.CLASS_TYPE_PARAMETER_BOUND:
7425  456 annotationRegistrant = new AnnotationRegistrant.ForTypeVariable.WithIndex.DoubleIndexed(descriptor,
7426    typePath,
7427    typeReference.getTypeParameterBoundIndex(),
7428    typeReference.getTypeParameterIndex(),
7429    typeVariableBoundsAnnotationTokens);
7430  456 break;
7431  0 default:
7432  0 throw new IllegalArgumentException("Unexpected type reference: " + typeReference.getSort());
7433    }
7434  798 return new AnnotationExtractor(annotationRegistrant, new ComponentTypeLocator.ForAnnotationProperty(Default.this, descriptor));
7435    }
7436   
 
7437  1857 toggle @Override
7438    public AnnotationVisitor visitAnnotation(String descriptor, boolean visible) {
7439  1857 return new AnnotationExtractor(descriptor, annotationTokens, new ComponentTypeLocator.ForAnnotationProperty(Default.this, descriptor));
7440    }
7441   
 
7442  8584 toggle @Override
7443    public FieldVisitor visitField(int modifiers, String internalName, String descriptor, String genericSignature, Object defaultValue) {
7444  8584 return new FieldExtractor(modifiers & REAL_MODIFIER_MASK, internalName, descriptor, genericSignature);
7445    }
7446   
 
7447  106682 toggle @Override
7448    public MethodVisitor visitMethod(int modifiers, String internalName, String descriptor, String genericSignature, String[] exceptionName) {
7449  106682 return internalName.equals(MethodDescription.TYPE_INITIALIZER_INTERNAL_NAME)
7450    ? IGNORE_METHOD
7451    : new MethodExtractor(modifiers & REAL_MODIFIER_MASK, internalName, descriptor, genericSignature, exceptionName);
7452    }
7453   
7454    /**
7455    * Creates a type description from all data that is currently collected. This method should only be invoked
7456    * after a class file was parsed fully.
7457    *
7458    * @return A type description reflecting the data that was collected by this instance.
7459    */
 
7460  4977 toggle protected TypeDescription toTypeDescription() {
7461  4977 return new LazyTypeDescription(Default.this,
7462    modifiers,
7463    internalName,
7464    superClassName,
7465    interfaceName,
7466    GenericTypeExtractor.ForSignature.OfType.extract(genericSignature),
7467    declarationContext,
7468    declaredTypes,
7469    anonymousType,
7470    superTypeAnnotationTokens,
7471    typeVariableAnnotationTokens,
7472    typeVariableBoundsAnnotationTokens,
7473    annotationTokens,
7474    fieldTokens,
7475    methodTokens);
7476    }
7477   
 
7478  0 toggle @Override
7479    public String toString() {
7480  0 return "TypePool.Default.TypeExtractor{" +
7481    "typePool=" + Default.this +
7482    ", annotationTokens=" + annotationTokens +
7483    ", fieldTokens=" + fieldTokens +
7484    ", methodTokens=" + methodTokens +
7485    ", modifiers=" + modifiers +
7486    ", internalName='" + internalName + '\'' +
7487    ", superClassName='" + superClassName + '\'' +
7488    ", genericSignature='" + genericSignature + '\'' +
7489    ", interfaceName=" + Arrays.toString(interfaceName) +
7490    ", anonymousType=" + anonymousType +
7491    ", declarationContext=" + declarationContext +
7492    '}';
7493    }
7494   
7495    /**
7496    * An annotation extractor reads an annotation found in a class field an collects data that
7497    * is relevant to creating a related annotation description.
7498    */
 
7499    protected class AnnotationExtractor extends AnnotationVisitor {
7500   
7501    /**
7502    * The annotation registrant to register found annotation values on.
7503    */
7504    private final AnnotationRegistrant annotationRegistrant;
7505   
7506    /**
7507    * A locator for the component type of any found annotation value.
7508    */
7509    private final ComponentTypeLocator componentTypeLocator;
7510   
7511    /**
7512    * Creates a new annotation extractor for a byte code element without an index.
7513    *
7514    * @param descriptor The annotation descriptor.
7515    * @param annotationTokens The collection for storing any discovered annotation tokens.
7516    * @param componentTypeLocator The component type locator to use.
7517    */
 
7518  20500 toggle protected AnnotationExtractor(String descriptor, List<LazyTypeDescription.AnnotationToken> annotationTokens, ComponentTypeLocator componentTypeLocator) {
7519  20500 this(new AnnotationRegistrant.ForByteCodeElement(descriptor, annotationTokens), componentTypeLocator);
7520    }
7521   
7522    /**
7523    * Creates a new annotation extractor for a byte code element with an index.
7524    *
7525    * @param descriptor The annotation descriptor.
7526    * @param index The index of the element for which the annotations are collected.
7527    * @param annotationTokens The collection for storing any discovered annotation tokens.
7528    * @param componentTypeLocator The component type locator to use.
7529    */
 
7530  412 toggle protected AnnotationExtractor(String descriptor,
7531    int index,
7532    Map<Integer, List<LazyTypeDescription.AnnotationToken>> annotationTokens,
7533    ComponentTypeLocator componentTypeLocator) {
7534  412 this(new AnnotationRegistrant.ForByteCodeElement.WithIndex(descriptor, index, annotationTokens), componentTypeLocator);
7535    }
7536   
7537    /**
7538    * Creates a new annotation extractor.
7539    *
7540    * @param annotationRegistrant The annotation registrant to register found annotation values on.
7541    * @param componentTypeLocator A locator for the component type of any found annotation value.
7542    */
 
7543  23786 toggle protected AnnotationExtractor(AnnotationRegistrant annotationRegistrant, ComponentTypeLocator componentTypeLocator) {
7544  23786 super(Opcodes.ASM5);
7545  23786 this.annotationRegistrant = annotationRegistrant;
7546  23786 this.componentTypeLocator = componentTypeLocator;
7547    }
7548   
 
7549  10479 toggle @Override
7550    public void visit(String name, Object value) {
7551  10479 annotationRegistrant.register(name, value instanceof Type
7552    ? new RawTypeValue(Default.this, (Type) value)
7553    : new AnnotationDescription.AnnotationValue.Trivial<Object>(value));
7554    }
7555   
 
7556  1810 toggle @Override
7557    public void visitEnum(String name, String descriptor, String value) {
7558  1810 annotationRegistrant.register(name, new RawEnumerationValue(Default.this, descriptor, value));
7559    }
7560   
 
7561  56 toggle @Override
7562    public AnnotationVisitor visitAnnotation(String name, String descriptor) {
7563  56 return new AnnotationExtractor(new AnnotationLookup(descriptor, name),
7564    new ComponentTypeLocator.ForAnnotationProperty(TypePool.Default.this, descriptor));
7565    }
7566   
 
7567  639 toggle @Override
7568    public AnnotationVisitor visitArray(String name) {
7569  639 return new AnnotationExtractor(new ArrayLookup(name, componentTypeLocator.bind(name)), ComponentTypeLocator.Illegal.INSTANCE);
7570    }
7571   
 
7572  23780 toggle @Override
7573    public void visitEnd() {
7574  23780 annotationRegistrant.onComplete();
7575    }
7576   
 
7577  18 toggle @Override
7578    public String toString() {
7579  18 return "TypePool.Default.TypeExtractor.AnnotationExtractor{" +
7580    "typeExtractor=" + TypeExtractor.this +
7581    "annotationRegistrant=" + annotationRegistrant +
7582    ", componentTypeLocator=" + componentTypeLocator +
7583    '}';
7584    }
7585   
7586    /**
7587    * An annotation registrant for registering values of an array.
7588    */
 
7589    protected class ArrayLookup implements AnnotationRegistrant {
7590   
7591    /**
7592    * The name of the annotation property the collected array is representing.
7593    */
7594    private final String name;
7595   
7596    /**
7597    * A lazy reference to resolve the component type of the collected array.
7598    */
7599    private final RawNonPrimitiveArray.ComponentTypeReference componentTypeReference;
7600   
7601    /**
7602    * A list of all annotation values that are found on this array.
7603    */
7604    private final List<AnnotationDescription.AnnotationValue<?, ?>> values;
7605   
7606    /**
7607    * Creates a new annotation registrant for an array lookup.
7608    *
7609    * @param name The name of the annotation property the collected array is representing.
7610    * @param componentTypeReference A lazy reference to resolve the component type of the collected array.
7611    */
 
7612  641 toggle protected ArrayLookup(String name, RawNonPrimitiveArray.ComponentTypeReference componentTypeReference) {
7613  641 this.name = name;
7614  641 this.componentTypeReference = componentTypeReference;
7615  641 values = new ArrayList<AnnotationDescription.AnnotationValue<?, ?>>();
7616    }
7617   
 
7618  1115 toggle @Override
7619    public void register(String ignored, AnnotationDescription.AnnotationValue<?, ?> annotationValue) {
7620  1115 values.add(annotationValue);
7621    }
7622   
 
7623  639 toggle @Override
7624    public void onComplete() {
7625  639 annotationRegistrant.register(name, new RawNonPrimitiveArray(Default.this, componentTypeReference, values));
7626    }
7627   
 
7628  5 toggle @Override
7629    public String toString() {
7630  5 return "TypePool.Default.TypeExtractor.AnnotationExtractor.ArrayLookup{" +
7631    "annotationExtractor=" + AnnotationExtractor.this +
7632    ", name='" + name + '\'' +
7633    ", componentTypeReference=" + componentTypeReference +
7634    ", values=" + values +
7635    '}';
7636    }
7637    }
7638   
7639    /**
7640    * An annotation registrant for registering the values on an array that is itself an annotation property.
7641    */
 
7642    protected class AnnotationLookup implements AnnotationRegistrant {
7643   
7644    /**
7645    * The descriptor of the original annotation for which the annotation values are looked up.
7646    */
7647    private final String descriptor;
7648   
7649    /**
7650    * The name of the original annotation for which the annotation values are looked up.
7651    */
7652    private final String name;
7653   
7654    /**
7655    * This annotation's values mapped by their attribute name.
7656    */
7657    private final Map<String, AnnotationDescription.AnnotationValue<?, ?>> values;
7658   
7659    /**
7660    * Creates a new annotation registrant for a recursive annotation lookup.
7661    *
7662    * @param name The name of the original annotation for which the annotation values are looked up.
7663    * @param descriptor The descriptor of the original annotation for which the annotation values are looked up.
7664    */
 
7665  58 toggle protected AnnotationLookup(String descriptor, String name) {
7666  58 this.descriptor = descriptor;
7667  58 this.name = name;
7668  58 values = new HashMap<String, AnnotationDescription.AnnotationValue<?, ?>>();
7669    }
7670   
 
7671  2 toggle @Override
7672    public void register(String name, AnnotationDescription.AnnotationValue<?, ?> annotationValue) {
7673  2 values.put(name, annotationValue);
7674    }
7675   
 
7676  56 toggle @Override
7677    public void onComplete() {
7678  56 annotationRegistrant.register(name, new RawAnnotationValue(Default.this, new LazyTypeDescription.AnnotationToken(descriptor, values)));
7679    }
7680   
 
7681  5 toggle @Override
7682    public String toString() {
7683  5 return "TypePool.Default.TypeExtractor.AnnotationExtractor.AnnotationLookup{" +
7684    "descriptor='" + descriptor + '\'' +
7685    ", name='" + name + '\'' +
7686    ", values=" + values +
7687    '}';
7688    }
7689    }
7690    }
7691   
7692    /**
7693    * A field extractor reads a field within a class file and collects data that is relevant
7694    * to creating a related field description.
7695    */
 
7696    protected class FieldExtractor extends FieldVisitor {
7697   
7698    /**
7699    * The modifiers found on the field.
7700    */
7701    private final int modifiers;
7702   
7703    /**
7704    * The name of the field.
7705    */
7706    private final String internalName;
7707   
7708    /**
7709    * The descriptor of the field type.
7710    */
7711    private final String descriptor;
7712   
7713    /**
7714    * The generic signature of the field or {@code null} if it is not generic.
7715    */
7716    private final String genericSignature;
7717   
7718    /**
7719    * A mapping of the field type's type annotations.
7720    */
7721    private final Map<String, List<LazyTypeDescription.AnnotationToken>> typeAnnotationTokens;
7722   
7723    /**
7724    * A list of annotation tokens found for this field.
7725    */
7726    private final List<LazyTypeDescription.AnnotationToken> annotationTokens;
7727   
7728    /**
7729    * Creates a new field extractor.
7730    *
7731    * @param modifiers The modifiers found for this field.
7732    * @param internalName The name of the field.
7733    * @param descriptor The descriptor of the field type.
7734    * @param genericSignature The generic signature of the field or {@code null} if it is not generic.
7735    */
 
7736  8586 toggle protected FieldExtractor(int modifiers,
7737    String internalName,
7738    String descriptor,
7739    String genericSignature) {
7740  8586 super(Opcodes.ASM5);
7741  8586 this.modifiers = modifiers;
7742  8586 this.internalName = internalName;
7743  8586 this.descriptor = descriptor;
7744  8586 this.genericSignature = genericSignature;
7745  8586 typeAnnotationTokens = new HashMap<String, List<LazyTypeDescription.AnnotationToken>>();
7746  8586 annotationTokens = new ArrayList<LazyTypeDescription.AnnotationToken>();
7747    }
7748   
 
7749  278 toggle @Override
7750    public AnnotationVisitor visitTypeAnnotation(int rawTypeReference, TypePath typePath, String descriptor, boolean visible) {
7751  278 AnnotationRegistrant annotationRegistrant;
7752  278 TypeReference typeReference = new TypeReference(rawTypeReference);
7753  278 switch (typeReference.getSort()) {
7754  278 case TypeReference.FIELD:
7755  278 annotationRegistrant = new AnnotationRegistrant.ForTypeVariable(descriptor, typePath, typeAnnotationTokens);
7756  278 break;
7757  0 default:
7758  0 throw new IllegalStateException("Unexpected type reference on field: " + typeReference.getSort());
7759    }
7760  278 return new AnnotationExtractor(annotationRegistrant, new ComponentTypeLocator.ForAnnotationProperty(Default.this, descriptor));
7761    }
7762   
 
7763  185 toggle @Override
7764    public AnnotationVisitor visitAnnotation(String descriptor, boolean visible) {
7765  185 return new AnnotationExtractor(descriptor, annotationTokens, new ComponentTypeLocator.ForAnnotationProperty(Default.this, descriptor));
7766    }
7767   
 
7768  8584 toggle @Override
7769    public void visitEnd() {
7770  8584 fieldTokens.add(new LazyTypeDescription.FieldToken(internalName,
7771    modifiers,
7772    descriptor,
7773    GenericTypeExtractor.ForSignature.OfField.extract(genericSignature),
7774    typeAnnotationTokens,
7775    annotationTokens));
7776    }
7777   
 
7778  14 toggle @Override
7779    public String toString() {
7780  14 return "TypePool.Default.TypeExtractor.FieldExtractor{" +
7781    "typeExtractor=" + TypeExtractor.this +
7782    ", modifiers=" + modifiers +
7783    ", internalName='" + internalName + '\'' +
7784    ", descriptor='" + descriptor + '\'' +
7785    ", genericSignature='" + genericSignature + '\'' +
7786    ", typeAnnotationTokens=" + typeAnnotationTokens +
7787    ", annotationTokens=" + annotationTokens +
7788    '}';
7789    }
7790    }
7791   
7792    /**
7793    * A method extractor reads a method within a class file and collects data that is relevant
7794    * to creating a related method description.
7795    */
 
7796    protected class MethodExtractor extends MethodVisitor implements AnnotationRegistrant {
7797   
7798    /**
7799    * The modifiers found for this method.
7800    */
7801    private final int modifiers;
7802   
7803    /**
7804    * The internal name found for this method.
7805    */
7806    private final String internalName;
7807   
7808    /**
7809    * The descriptor found for this method.
7810    */
7811    private final String descriptor;
7812   
7813    /**
7814    * The generic signature of the method or {@code null} if it is not generic.
7815    */
7816    private final String genericSignature;
7817   
7818    /**
7819    * An array of internal names of the exceptions of the found method
7820    * or {@code null} if there are no such exceptions.
7821    */
7822    private final String[] exceptionName;
7823   
7824    /**
7825    * A mapping of the method's type variables' type annotations by their indices.
7826    */
7827    private final Map<Integer, Map<String, List<LazyTypeDescription.AnnotationToken>>> typeVariableAnnotationTokens;
7828   
7829    /**
7830    * A mapping of the method's type variables' bounds' type annotations by their indices and each variable's index.
7831    */
7832    private final Map<Integer, Map<Integer, Map<String, List<LazyTypeDescription.AnnotationToken>>>> typeVariableBoundAnnotationTokens;
7833   
7834    /**
7835    * A mapping of the method's return type's type annotations.
7836    */
7837    private final Map<String, List<LazyTypeDescription.AnnotationToken>> returnTypeAnnotationTokens;
7838   
7839    /**
7840    * A mapping of the parameters' type annotations by their indices.
7841    */
7842    private final Map<Integer, Map<String, List<LazyTypeDescription.AnnotationToken>>> parameterTypeAnnotationTokens;
7843   
7844    /**
7845    * A mapping of the exception types' type annotations by their indices.
7846    */
7847    private final Map<Integer, Map<String, List<LazyTypeDescription.AnnotationToken>>> exceptionTypeAnnotationTokens;
7848   
7849    /**
7850    * A mapping of the receiver type's type annotations.
7851    */
7852    private final Map<String, List<LazyTypeDescription.AnnotationToken>> receiverTypeAnnotationTokens;
7853   
7854    /**
7855    * A list of annotation tokens declared on the found method.
7856    */
7857    private final List<LazyTypeDescription.AnnotationToken> annotationTokens;
7858   
7859    /**
7860    * A mapping of parameter indices to annotation tokens found for the parameters at these indices.
7861    */
7862    private final Map<Integer, List<LazyTypeDescription.AnnotationToken>> parameterAnnotationTokens;
7863   
7864    /**
7865    * A list of tokens representing meta information of a parameter as it is available for method's
7866    * that are compiled in the Java 8 version format.
7867    */
7868    private final List<LazyTypeDescription.MethodToken.ParameterToken> parameterTokens;
7869   
7870    /**
7871    * A bag of parameter meta information representing debugging information which allows to extract
7872    * a method's parameter names.
7873    */
7874    private final ParameterBag legacyParameterBag;
7875   
7876    /**
7877    * The first label that is found in the method's body, if any, denoting the start of the method.
7878    * This label can be used to identify names of local variables that describe the method's parameters.
7879    */
7880    private Label firstLabel;
7881   
7882    /**
7883    * The default value of the found method or {@code null} if no such value exists.
7884    */
7885    private AnnotationDescription.AnnotationValue<?, ?> defaultValue;
7886   
7887    /**
7888    * Creates a method extractor.
7889    *
7890    * @param modifiers The modifiers found for this method.
7891    * @param internalName The internal name found for this method.
7892    * @param descriptor The descriptor found for this method.
7893    * @param genericSignature The generic signature of the method or {@code null} if it is not generic.
7894    * @param exceptionName An array of internal names of the exceptions of the found method
7895    * or {@code null} if there are no such exceptions.
7896    */
 
7897  105207 toggle protected MethodExtractor(int modifiers,
7898    String internalName,
7899    String descriptor,
7900    String genericSignature,
7901    String[] exceptionName) {
7902  105207 super(Opcodes.ASM5);
7903  105207 this.modifiers = modifiers;
7904  105207 this.internalName = internalName;
7905  105207 this.descriptor = descriptor;
7906  105207 this.genericSignature = genericSignature;
7907  105207 this.exceptionName = exceptionName;
7908  105207 typeVariableAnnotationTokens = new HashMap<Integer, Map<String, List<LazyTypeDescription.AnnotationToken>>>();
7909  105207 typeVariableBoundAnnotationTokens = new HashMap<Integer, Map<Integer, Map<String, List<LazyTypeDescription.AnnotationToken>>>>();
7910  105207 returnTypeAnnotationTokens = new HashMap<String, List<LazyTypeDescription.AnnotationToken>>();
7911  105207 parameterTypeAnnotationTokens = new HashMap<Integer, Map<String, List<LazyTypeDescription.AnnotationToken>>>();
7912  105207 exceptionTypeAnnotationTokens = new HashMap<Integer, Map<String, List<LazyTypeDescription.AnnotationToken>>>();
7913  105207 receiverTypeAnnotationTokens = new HashMap<String, List<LazyTypeDescription.AnnotationToken>>();
7914  105207 annotationTokens = new ArrayList<LazyTypeDescription.AnnotationToken>();
7915  105207 parameterAnnotationTokens = new HashMap<Integer, List<LazyTypeDescription.AnnotationToken>>();
7916  105207 parameterTokens = new ArrayList<LazyTypeDescription.MethodToken.ParameterToken>();
7917  105207 legacyParameterBag = new ParameterBag(Type.getMethodType(descriptor).getArgumentTypes());
7918    }
7919   
 
7920  1016 toggle @Override
7921    public AnnotationVisitor visitTypeAnnotation(int rawTypeReference, TypePath typePath, String descriptor, boolean visible) {
7922  1016 AnnotationRegistrant annotationRegistrant;
7923  1016 TypeReference typeReference = new TypeReference(rawTypeReference);
7924  1016 switch (typeReference.getSort()) {
7925  38 case TypeReference.METHOD_TYPE_PARAMETER:
7926  38 annotationRegistrant = new ForTypeVariable.WithIndex(descriptor,
7927    typePath,
7928    typeReference.getTypeParameterIndex(),
7929    typeVariableAnnotationTokens);
7930  38 break;
7931  38 case TypeReference.METHOD_TYPE_PARAMETER_BOUND:
7932  38 annotationRegistrant = new ForTypeVariable.WithIndex.DoubleIndexed(descriptor,
7933    typePath,
7934    typeReference.getTypeParameterBoundIndex(),
7935    typeReference.getTypeParameterIndex(),
7936    typeVariableBoundAnnotationTokens);
7937  38 break;
7938  280 case TypeReference.METHOD_RETURN:
7939  280 annotationRegistrant = new ForTypeVariable(descriptor,
7940    typePath,
7941    returnTypeAnnotationTokens);
7942  280 break;
7943  356 case TypeReference.METHOD_FORMAL_PARAMETER:
7944  356 annotationRegistrant = new ForTypeVariable.WithIndex(descriptor,
7945    typePath,
7946    typeReference.getFormalParameterIndex(),
7947    parameterTypeAnnotationTokens);
7948  356 break;
7949  90 case TypeReference.THROWS:
7950  90 annotationRegistrant = new ForTypeVariable.WithIndex(descriptor,
7951    typePath,
7952    typeReference.getExceptionIndex(),
7953    exceptionTypeAnnotationTokens);
7954  90 break;
7955  214 case TypeReference.METHOD_RECEIVER:
7956  214 annotationRegistrant = new ForTypeVariable(descriptor,
7957    typePath,
7958    receiverTypeAnnotationTokens);
7959  214 break;
7960  0 default:
7961  0 throw new IllegalStateException("Unexpected type reference on method: " + typeReference.getSort());
7962    }
7963  1016 return new AnnotationExtractor(annotationRegistrant, new ComponentTypeLocator.ForAnnotationProperty(Default.this, descriptor));
7964    }
7965   
 
7966  18456 toggle @Override
7967    public AnnotationVisitor visitAnnotation(String descriptor, boolean visible) {
7968  18456 return new AnnotationExtractor(descriptor, annotationTokens, new ComponentTypeLocator.ForAnnotationProperty(Default.this, descriptor));
7969    }
7970   
 
7971  410 toggle @Override
7972    public AnnotationVisitor visitParameterAnnotation(int index, String descriptor, boolean visible) {
7973  410 return new AnnotationExtractor(descriptor, index, parameterAnnotationTokens, new ComponentTypeLocator.ForAnnotationProperty(Default.this, descriptor));
7974    }
7975   
 
7976  664912 toggle @Override
7977    public void visitLabel(Label label) {
7978  664912 if (readerMode.isExtended() && firstLabel == null) {
7979  79765 firstLabel = label;
7980    }
7981    }
7982   
 
7983  77602 toggle @Override
7984    public void visitLocalVariable(String name, String descriptor, String signature, Label start, Label end, int index) {
7985  77602 if (readerMode.isExtended() && start == firstLabel) {
7986  28694 legacyParameterBag.register(index, name);
7987    }
7988    }
7989   
 
7990  208 toggle @Override
7991    public void visitParameter(String name, int modifiers) {
7992  208 parameterTokens.add(new LazyTypeDescription.MethodToken.ParameterToken(name, modifiers));
7993    }
7994   
 
7995  85 toggle @Override
7996    public AnnotationVisitor visitAnnotationDefault() {
7997  85 return new AnnotationExtractor(this, new ComponentTypeLocator.ForArrayType(descriptor));
7998    }
7999   
 
8000  85 toggle @Override
8001    public void register(String ignored, AnnotationDescription.AnnotationValue<?, ?> annotationValue) {
8002  85 defaultValue = annotationValue;
8003    }
8004   
 
8005  85 toggle @Override
8006    public void onComplete() {
8007    /* do nothing, as the register method is called at most once for default values */
8008    }
8009   
 
8010  105205 toggle @Override
8011    public void visitEnd() {
8012  105205 methodTokens.add(new LazyTypeDescription.MethodToken(internalName,
8013    modifiers,
8014    descriptor,
8015    GenericTypeExtractor.ForSignature.OfMethod.extract(genericSignature),
8016    exceptionName,
8017    typeVariableAnnotationTokens,
8018    typeVariableBoundAnnotationTokens,
8019    returnTypeAnnotationTokens,
8020    parameterTypeAnnotationTokens,
8021    exceptionTypeAnnotationTokens,
8022    receiverTypeAnnotationTokens,
8023    annotationTokens,
8024    parameterAnnotationTokens,
8025  105205 parameterTokens.isEmpty()
8026    ? legacyParameterBag.resolve((modifiers & Opcodes.ACC_STATIC) != 0)
8027    : parameterTokens,
8028    defaultValue));
8029    }
8030   
 
8031  36 toggle @Override
8032    public String toString() {
8033  36 return "TypePool.Default.TypeExtractor.MethodExtractor{" +
8034    "typeExtractor=" + TypeExtractor.this +
8035    ", modifiers=" + modifiers +
8036    ", internalName='" + internalName + '\'' +
8037    ", descriptor='" + descriptor + '\'' +
8038    ", genericSignature='" + genericSignature + '\'' +
8039    ", exceptionName=" + Arrays.toString(exceptionName) +
8040    ", typeVariableAnnotationTokens=" + typeVariableAnnotationTokens +
8041    ", typeVariableBoundAnnotationTokens=" + typeVariableBoundAnnotationTokens +
8042    ", returnTypeAnnotationTokens=" + returnTypeAnnotationTokens +
8043    ", parameterTypeAnnotationTokens=" + parameterTypeAnnotationTokens +
8044    ", exceptionTypeAnnotationTokens=" + exceptionTypeAnnotationTokens +
8045    ", receiverTypeAnnotationTokens=" + receiverTypeAnnotationTokens +
8046    ", annotationTokens=" + annotationTokens +
8047    ", parameterAnnotationTokens=" + parameterAnnotationTokens +
8048    ", parameterTokens=" + parameterTokens +
8049    ", legacyParameterBag=" + legacyParameterBag +
8050    ", firstLabel=" + firstLabel +
8051    ", defaultValue=" + defaultValue +
8052    '}';
8053    }
8054    }
8055    }
8056   
8057    /**
8058    * Determines the granularity of the class file parsing that is conducted by a {@link net.bytebuddy.pool.TypePool.Default}.
8059    */
 
8060    public enum ReaderMode {
8061   
8062    /**
8063    * The extended reader mode parses the code segment of each method in order to detect parameter names
8064    * that are only stored in a method's debugging information but are not explicitly included.
8065    */
8066    EXTENDED(ClassReader.SKIP_FRAMES),
8067   
8068    /**
8069    * The fast reader mode skips the code segment of each method and cannot detect parameter names that are
8070    * only contained within the debugging information. This mode still detects explicitly included method
8071    * parameter names.
8072    */
8073    FAST(ClassReader.SKIP_CODE);
8074   
8075    /**
8076    * The flags to provide to a {@link ClassReader} for parsing a file.
8077    */
8078    private final int flags;
8079   
8080    /**
8081    * Creates a new reader mode constant.
8082    *
8083    * @param flags The flags to provide to a {@link ClassReader} for parsing a file.
8084    */
 
8085  2 toggle ReaderMode(int flags) {
8086  2 this.flags = flags;
8087    }
8088   
8089    /**
8090    * Returns the flags to provide to a {@link ClassReader} for parsing a file.
8091    *
8092    * @return The flags to provide to a {@link ClassReader} for parsing a file.
8093    */
 
8094  4979 toggle protected int getFlags() {
8095  4979 return flags;
8096    }
8097   
8098    /**
8099    * Determines if this reader mode represents extended reading.
8100    *
8101    * @return {@code true} if this reader mode represents extended reading.
8102    */
 
8103  742516 toggle public boolean isExtended() {
8104  742516 return this == EXTENDED;
8105    }
8106   
 
8107  18 toggle @Override
8108    public String toString() {
8109  18 return "TypePool.Default.ReaderMode." + name();
8110    }
8111    }
8112    }
8113   
8114    /**
8115    * A lazy facade of a type pool that delegates any lookups to another type pool only if another value than the type's name is looked up.
8116    */
 
8117    class LazyFacade extends AbstractBase {
8118   
8119    /**
8120    * The type pool to delegate to.
8121    */
8122    private final TypePool typePool;
8123   
8124    /**
8125    * Creates a lazy facade for a type pool.
8126    *
8127    * @param typePool The type pool to delegate to.
8128    */
 
8129  48690 toggle public LazyFacade(TypePool typePool) {
8130  48690 super(CacheProvider.NoOp.INSTANCE);
8131  48690 this.typePool = typePool;
8132    }
8133   
 
8134  48474 toggle @Override
8135    protected Resolution doDescribe(String name) {
8136  48474 return new LazyResolution(typePool, name);
8137    }
8138   
 
8139  547 toggle @Override
8140    public void clear() {
8141  547 typePool.clear();
8142    }
8143   
 
8144  9 toggle @Override
8145    public boolean equals(Object other) {
8146  9 return this == other || !(other == null || getClass() != other.getClass())
8147    && typePool.equals(((LazyFacade) other).typePool);
8148    }
8149   
 
8150  3 toggle @Override
8151    public int hashCode() {
8152  3 return typePool.hashCode();
8153    }
8154   
 
8155  4 toggle @Override
8156    public String toString() {
8157  4 return "TypePool.LazyFacade{" +
8158    "typePool=" + typePool +
8159    '}';
8160    }
8161   
8162    /**
8163    * The lazy resolution for a lazy facade for a type pool.
8164    */
 
8165    protected static class LazyResolution implements Resolution {
8166   
8167    /**
8168    * The type pool to delegate to.
8169    */
8170    private final TypePool typePool;
8171   
8172    /**
8173    * The name of the type that is represented by this resolution.
8174    */
8175    private final String name;
8176   
8177    /**
8178    * Creates a lazy resolution for a lazy facade for a type pool.
8179    *
8180    * @param typePool The type pool to delegate to.
8181    * @param name The name of the type that is represented by this resolution.
8182    */
 
8183  48478 toggle protected LazyResolution(TypePool typePool, String name) {
8184  48478 this.typePool = typePool;
8185  48478 this.name = name;
8186    }
8187   
 
8188  1 toggle @Override
8189    public boolean isResolved() {
8190  1 return typePool.describe(name).isResolved();
8191    }
8192   
 
8193  48473 toggle @Override
8194    public TypeDescription resolve() {
8195  48473 return new LazyTypeDescription(typePool, name);
8196    }
8197   
 
8198  6 toggle @Override
8199    public boolean equals(Object other) {
8200  1 if (this == other) return true;
8201  2 if (other == null || getClass() != other.getClass()) return false;
8202  3 LazyResolution that = (LazyResolution) other;
8203  3 return typePool.equals(that.typePool) && name.equals(that.name);
8204    }
8205   
 
8206  4 toggle @Override
8207    public int hashCode() {
8208  4 int result = typePool.hashCode();
8209  4 result = 31 * result + name.hashCode();
8210  4 return result;
8211    }
8212   
 
8213  4 toggle @Override
8214    public String toString() {
8215  4 return "TypePool.LazyFacade.LazyResolution{" +
8216    "typePool=" + typePool +
8217    ", name=" + name +
8218    '}';
8219    }
8220   
8221    /**
8222    * A lazy type description for a lazy facade of a type pool.
8223    */
 
8224    protected static class LazyTypeDescription extends TypeDescription.AbstractBase.OfSimpleType {
8225   
8226    /**
8227    * The type pool to delegate to.
8228    */
8229    private final TypePool typePool;
8230   
8231    /**
8232    * The name of the type that is represented by this resolution.
8233    */
8234    private final String name;
8235   
8236    /**
8237    * Creates a lazy type description for a lazy facade of a type pool.
8238    *
8239    * @param typePool The type pool to delegate to.
8240    * @param name The name of the type that is represented by this resolution.
8241    */
 
8242  48473 toggle protected LazyTypeDescription(TypePool typePool, String name) {
8243  48473 this.typePool = typePool;
8244  48473 this.name = name;
8245    }
8246   
8247    /**
8248    * Resolves the actual type by querying the actual type pool.
8249    *
8250    * @return A representation of the actual type description.
8251    */
 
8252  2102 toggle private TypeDescription resolve() {
8253  2102 return typePool.describe(name).resolve();
8254    }
8255   
 
8256  178 toggle @Override
8257    public Generic getSuperClass() {
8258  178 return resolve().getSuperClass();
8259    }
8260   
 
8261  251 toggle @Override
8262    public TypeList.Generic getInterfaces() {
8263  251 return resolve().getInterfaces();
8264    }
8265   
 
8266  203 toggle @Override
8267    public FieldList<FieldDescription.InDefinedShape> getDeclaredFields() {
8268  203 return resolve().getDeclaredFields();
8269    }
8270   
 
8271  267 toggle @Override
8272    public MethodList<MethodDescription.InDefinedShape> getDeclaredMethods() {
8273  267 return resolve().getDeclaredMethods();
8274    }
8275   
 
8276  88 toggle @Override
8277    public TypeDescription getDeclaringType() {
8278  88 return resolve().getDeclaringType();
8279    }
8280   
 
8281  85 toggle @Override
8282    public MethodDescription getEnclosingMethod() {
8283  85 return resolve().getEnclosingMethod();
8284    }
8285   
 
8286  85 toggle @Override
8287    public TypeDescription getEnclosingType() {
8288  85 return resolve().getEnclosingType();
8289    }
8290   
 
8291  82 toggle @Override
8292    public TypeList getDeclaredTypes() {
8293  82 return resolve().getDeclaredTypes();
8294    }
8295   
 
8296  90 toggle @Override
8297    public boolean isAnonymousClass() {
8298  90 return resolve().isAnonymousClass();
8299    }
8300   
 
8301  89 toggle @Override
8302    public boolean isLocalClass() {
8303  89 return resolve().isLocalClass();
8304    }
8305   
 
8306  84 toggle @Override
8307    public boolean isMemberClass() {
8308  84 return resolve().isMemberClass();
8309    }
8310   
 
8311  7 toggle @Override
8312    public PackageDescription getPackage() {
8313  7 return resolve().getPackage();
8314    }
8315   
 
8316  259 toggle @Override
8317    public AnnotationList getDeclaredAnnotations() {
8318  259 return resolve().getDeclaredAnnotations();
8319    }
8320   
 
8321  172 toggle @Override
8322    public TypeList.Generic getTypeVariables() {
8323  172 return resolve().getTypeVariables();
8324    }
8325   
 
8326  162 toggle @Override
8327    public int getModifiers() {
8328  162 return resolve().getModifiers();
8329    }
8330   
 
8331  49063 toggle @Override
8332    public String getName() {
8333  49063 return name;
8334    }
8335    }
8336    }
8337    }
8338   
8339    /**
8340    * A type pool that attempts to load a class.
8341    */
 
8342    class ClassLoading extends AbstractBase.Hierarchical {
8343   
8344    /**
8345    * The class loader to query.
8346    */
8347    private final ClassLoader classLoader;
8348   
8349    /**
8350    * Creates a class loadings type pool.
8351    *
8352    * @param cacheProvider The cache provider to use.
8353    * @param parent The parent type pool.
8354    * @param classLoader The class loader to use for locating files.
8355    */
 
8356  25266 toggle public ClassLoading(CacheProvider cacheProvider, TypePool parent, ClassLoader classLoader) {
8357  25266 super(cacheProvider, parent);
8358  25266 this.classLoader = classLoader;
8359    }
8360   
8361    /**
8362    * Returns a type pool that attempts type descriptions by loadings types from the given class loader.
8363    *
8364    * @param classLoader The class loader to use.
8365    * @return An class loading type pool.
8366    */
 
8367  903 toggle public static TypePool of(ClassLoader classLoader) {
8368  903 return of(classLoader, Empty.INSTANCE);
8369    }
8370   
8371    /**
8372    * Returns a type pool that attempts type descriptions by loadings types from the given class loader.
8373    *
8374    * @param classLoader The class loader to use.
8375    * @param parent The parent type pool to use.
8376    * @return An class loading type pool.
8377    */
 
8378  25256 toggle public static TypePool of(ClassLoader classLoader, TypePool parent) {
8379  25256 return new ClassLoading(CacheProvider.NoOp.INSTANCE, parent, classLoader);
8380    }
8381   
8382    /**
8383    * Returns a type pool that attempts type descriptions by loadings types from the system class loader.
8384    *
8385    * @return An class loading type pool.
8386    */
 
8387  901 toggle public static TypePool ofClassPath() {
8388  901 return of(ClassLoader.getSystemClassLoader());
8389    }
8390   
 
8391  8 toggle @Override
8392    public Resolution doDescribe(String name) {
8393  8 try {
8394  8 return new Resolution.Simple(new TypeDescription.ForLoadedType(Class.forName(name, false, classLoader)));
8395    } catch (ClassNotFoundException ignored) {
8396  0 return new Resolution.Illegal(name);
8397    }
8398    }
8399   
 
8400  14 toggle @Override
8401    public boolean equals(Object other) {
8402  2 if (this == other) return true;
8403  4 if (other == null || getClass() != other.getClass()) return false;
8404  4 if (!super.equals(other)) return false;
8405  4 ClassLoading that = (ClassLoading) other;
8406  4 return !(classLoader != null ? !classLoader.equals(that.classLoader) : that.classLoader != null);
8407    }
8408   
 
8409  10 toggle @Override
8410    public int hashCode() {
8411  10 int result = super.hashCode();
8412  10 result = 31 * result + (classLoader != null ? classLoader.hashCode() : 0);
8413  10 return result;
8414    }
8415   
 
8416  10 toggle @Override
8417    public String toString() {
8418  10 return "TypePool.ClassLoading{" +
8419    ", cacheProvider=" + cacheProvider +
8420    ", classLoader=" + classLoader +
8421    '}';
8422    }
8423    }
8424   
8425    /**
8426    * A type pool that supplies explicitly known type descriptions.
8427    */
 
8428    class Explicit extends AbstractBase.Hierarchical {
8429   
8430    /**
8431    * A mapping from type names to type descriptions of that name.
8432    */
8433    private final Map<String, TypeDescription> precomputed;
8434   
8435    /**
8436    * Creates a new explicit type pool.
8437    *
8438    * @param parent The parent type pool.
8439    * @param precomputed A mapping from type names to type descriptions of that name.
8440    */
 
8441  8 toggle public Explicit(TypePool parent, Map<String, TypeDescription> precomputed) {
8442  8 super(CacheProvider.NoOp.INSTANCE, parent);
8443  8 this.precomputed = precomputed;
8444    }
8445   
 
8446  2 toggle @Override
8447    protected Resolution doDescribe(String name) {
8448  2 TypeDescription typeDescription = precomputed.get(name);
8449  2 return typeDescription == null
8450    ? new Resolution.Illegal(name)
8451    : new Resolution.Simple(typeDescription);
8452    }
8453   
 
8454  6 toggle @Override
8455    public boolean equals(Object other) {
8456  6 return this == other || !(other == null || getClass() != other.getClass())
8457    && super.equals(other)
8458    && precomputed.equals(((Explicit) other).precomputed);
8459    }
8460   
 
8461  4 toggle @Override
8462    public int hashCode() {
8463  4 int result = super.hashCode();
8464  4 result = 31 * result + precomputed.hashCode();
8465  4 return result;
8466    }
8467   
 
8468  5 toggle @Override
8469    public String toString() {
8470  5 return "TypePool.Explicit{" +
8471    "cacheProvider=" + cacheProvider +
8472    ", precomputed=" + precomputed +
8473    '}';
8474    }
8475    }
8476    }